comparison src/rvous.c @ 221:b2f9f629525e

[gaim-migrate @ 231] Added on the beginnings of file sending. Win clients can now figure out which file you're *trying* to send them, but can't get it. The AIM method of Get File is really fscked up, IMHO. I don't know if any of you are familiar with it, but I'll describe it. Some user decides they want to download a file from another user, so they choose Get File. It then returns a list of files available from that person, and they can choose which ones they want to download. The other person can't decide on a user-by-user basis which files are listed, only if any files are listed at all (not allowing people to download them). The way I'm going to implement it is when someone gets a message that another person is trying to download a file from them, it asks them which file they want to make available. You can only do one file at a time this way, but that's tough if you want to be downloading more than one file. Use gnutella or FTP or something that's better designed for it than AIM. But the way the win AIM clients are now, it acts as a public ftp server, and I think it shouldn't. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sun, 07 May 2000 01:50:06 +0000
parents 1a5ee1f8b39e
children 6ced2f1c8b24
comparison
equal deleted inserted replaced
220:d25b1484011b 221:b2f9f629525e
132 132
133 gtk_widget_show(ft->window); 133 gtk_widget_show(ft->window);
134 134
135 g_free(buf); 135 g_free(buf);
136 g_free(fname); 136 g_free(fname);
137 }
138
139 static int read_file_header(int fd, struct file_header *header) {
140 char buf[257];
141 int read_rv = read(fd, buf, 256);
142 memcpy(&header->magic, buf + 0, 4);
143 memcpy(&header->hdrlen, buf + 4, 2);
144 memcpy(&header->hdrtype, buf + 6, 2);
145 memcpy(&header->bcookie, buf + 8, 8);
146 memcpy(&header->encrypt, buf + 16, 2);
147 memcpy(&header->compress, buf + 18, 2);
148 memcpy(&header->totfiles, buf + 20, 2);
149 memcpy(&header->filesleft, buf + 22, 2);
150 memcpy(&header->totparts, buf + 24, 2);
151 memcpy(&header->partsleft, buf + 26, 2);
152 memcpy(&header->totsize, buf + 28, 4);
153 memcpy(&header->size, buf + 32, 4);
154 memcpy(&header->modtime, buf + 36, 4);
155 memcpy(&header->checksum, buf + 40, 4);
156 memcpy(&header->rfrcsum, buf + 44, 4);
157 memcpy(&header->rfsize, buf + 48, 4);
158 memcpy(&header->cretime, buf + 52, 4);
159 memcpy(&header->rfcsum, buf + 56, 4);
160 memcpy(&header->nrecvd, buf + 60, 4);
161 memcpy(&header->recvcsum, buf + 64, 4);
162 memcpy(&header->idstring, buf + 68, 32);
163 memcpy(&header->flags, buf + 100, 1);
164 memcpy(&header->lnameoffset, buf + 101, 1);
165 memcpy(&header->lsizeoffset, buf + 102, 1);
166 memcpy(&header->dummy, buf + 103, 69);
167 memcpy(&header->macfileinfo, buf + 172, 16);
168 memcpy(&header->nencode, buf + 188, 2);
169 memcpy(&header->nlanguage, buf + 190, 2);
170 memcpy(&header->name, buf + 192, 64);
171 return read_rv;
137 } 172 }
138 173
139 static int write_file_header(int fd, struct file_header *header) { 174 static int write_file_header(int fd, struct file_header *header) {
140 char buf[257]; 175 char buf[257];
141 memcpy(buf + 0, &header->magic, 4); 176 memcpy(buf + 0, &header->magic, 4);
211 fclose(ft->f); 246 fclose(ft->f);
212 free_ft(ft); 247 free_ft(ft);
213 return; 248 return;
214 } 249 }
215 250
216 read_rv = read(ft->fd, header, 256); 251 read_rv = read_file_header(ft->fd, header);
217 if(read_rv < 0) { 252 if(read_rv < 0) {
218 close(ft->fd); 253 close(ft->fd);
219 fclose(ft->f); 254 fclose(ft->f);
220 g_free(header); 255 g_free(header);
221 free_ft(ft); 256 free_ft(ft);
277 if (errno == EWOULDBLOCK) { 312 if (errno == EWOULDBLOCK) {
278 while(gtk_events_pending()) 313 while(gtk_events_pending())
279 gtk_main_iteration(); 314 gtk_main_iteration();
280 continue; 315 continue;
281 } 316 }
317 gtk_widget_destroy(fw);
318 fw = NULL;
282 fclose(ft->f); 319 fclose(ft->f);
283 close(ft->fd); 320 close(ft->fd);
284 g_free(buf); 321 g_free(buf);
285 g_free(header); 322 g_free(header);
286 free_ft(ft); 323 free_ft(ft);
331 char *buf; 368 char *buf;
332 int read_rv; 369 int read_rv;
333 struct file_header *fhdr = g_new0(struct file_header, 1); 370 struct file_header *fhdr = g_new0(struct file_header, 1);
334 struct sockaddr_in sin; 371 struct sockaddr_in sin;
335 guint32 rcv; 372 guint32 rcv;
373 int cont;
336 char *c; 374 char *c;
337 struct stat st; 375 struct stat st;
338 struct tm *fortime; 376 struct tm *fortime;
377 GtkWidget *fw = NULL, *fbar = NULL, *label = NULL;
378 GtkWidget *button = NULL, *pct = NULL;
339 379
340 stat(file, &st); 380 stat(file, &st);
341 if (!(ft->f = fopen(file, "r"))) { 381 if (!(ft->f = fopen(file, "r"))) {
342 buf = g_malloc(BUF_LONG); 382 buf = g_malloc(BUF_LONG);
343 g_snprintf(buf, BUF_LONG / 2, "Error reading file %s", file); 383 g_snprintf(buf, BUF_LONG / 2, "Error reading file %s", file);
344 do_error_dialog(buf, "Error"); 384 do_error_dialog(buf, "Error");
345 g_free(buf); 385 g_free(buf);
346 ft->accepted = 0; 386 ft->accepted = 0;
347 accept_callback(NULL, ft); 387 accept_callback(NULL, ft);
388 free_ft(ft);
348 return; 389 return;
349 } 390 }
350 391
351 ft->accepted = 1; 392 ft->accepted = 1;
352 393
357 sflap_send(send, strlen(send), TYPE_DATA); 398 sflap_send(send, strlen(send), TYPE_DATA);
358 g_free(send); 399 g_free(send);
359 400
360 401
361 402
362 sin.sin_addr.s_addr = inet_addr(ft->ip); 403 ft->fd = connect_address(inet_addr(ft->ip), ft->port);
363 sin.sin_family = AF_INET; 404
364 sin.sin_port = htons(ft->port); 405 if (ft->fd <= -1) {
365 406 g_free(fhdr);
366 ft->fd = socket(AF_INET, SOCK_STREAM, 0); 407 free_ft(ft);
367
368 if (ft->fd <= -1 || connect(ft->fd, (struct sockaddr *)&sin, sizeof(sin))) {
369 return; 408 return;
370 } 409 }
371 410
372 /* here's where we differ from do_get_file */ 411 /* here's where we differ from do_get_file */
373 /* 1. build/send header 412 /* 1. build/send header
374 * 2. receive header 413 * 2. receive header
375 * 3. send listing file 414 * 3. send listing file
376 * 4. receive header 415 * 4. receive header
377 * 416 *
378 * then we need to wait to actually send the file. 417 * then we need to wait to actually send the file.
418 *
419 * 5. either (receive header) or (remote host cancels)
420 * 6. if received header, send file
421 * 7. ? haven't gotten this far yet
379 */ 422 */
380 423
381 /* 1. build/send header */ 424 /* 1. build/send header */
382 c = file + strlen(file); 425 c = file + strlen(file);
383 while (*(c - 1) != '/') c--; 426 while (*(c - 1) != '/') c--;
396 fhdr->filesleft = htons(1); 439 fhdr->filesleft = htons(1);
397 fhdr->totparts = htons(1); 440 fhdr->totparts = htons(1);
398 fhdr->partsleft = htons(1); 441 fhdr->partsleft = htons(1);
399 fhdr->totsize = htonl((long)st.st_size); /* combined size of all files */ 442 fhdr->totsize = htonl((long)st.st_size); /* combined size of all files */
400 /* size = strlen("mm/dd/yyyy hh:mm sizesize 'name'\r\n") */ 443 /* size = strlen("mm/dd/yyyy hh:mm sizesize 'name'\r\n") */
401 fhdr->size = htonl(30 + strlen(c)); /* size of listing.txt */ 444 fhdr->size = htonl(28 + strlen(c)); /* size of listing.txt */
402 fhdr->modtime = htonl(time(NULL)); /* time since UNIX epoch */ 445 fhdr->modtime = htonl(time(NULL)); /* time since UNIX epoch */
403 fhdr->checksum = htonl(0x89f70000); /* ? */ 446 fhdr->checksum = htonl(0x89f70000); /* ? i don't think this matters */
404 fhdr->rfrcsum = 0; 447 fhdr->rfrcsum = 0;
405 fhdr->rfsize = 0; 448 fhdr->rfsize = 0;
406 fhdr->cretime = 0; 449 fhdr->cretime = 0;
407 fhdr->rfcsum = 0; 450 fhdr->rfcsum = 0;
408 fhdr->nrecvd = 0; 451 fhdr->nrecvd = 0;
418 snprintf(fhdr->name, 64, "listing.txt"); 461 snprintf(fhdr->name, 64, "listing.txt");
419 read_rv = write_file_header(ft->fd, fhdr); 462 read_rv = write_file_header(ft->fd, fhdr);
420 if (read_rv <= -1) { 463 if (read_rv <= -1) {
421 sprintf(debug_buff, "Couldn't write opening header\n"); 464 sprintf(debug_buff, "Couldn't write opening header\n");
422 debug_print(debug_buff); 465 debug_print(debug_buff);
466 g_free(fhdr);
423 close(ft->fd); 467 close(ft->fd);
468 free_ft(ft);
424 return; 469 return;
425 } 470 }
426 471
427 /* 2. receive header */ 472 /* 2. receive header */
428 sprintf(debug_buff, "Receiving header\n"); 473 sprintf(debug_buff, "Receiving header\n");
429 debug_print(debug_buff); 474 debug_print(debug_buff);
430 read_rv = read(ft->fd, fhdr, 256); 475 read_rv = read_file_header(ft->fd, fhdr);
431 if (read_rv <= -1) { 476 if (read_rv <= -1) {
432 sprintf(debug_buff, "Couldn't read header\n"); 477 sprintf(debug_buff, "Couldn't read header\n");
433 debug_print(debug_buff); 478 debug_print(debug_buff);
479 g_free(fhdr);
434 close(ft->fd); 480 close(ft->fd);
481 free_ft(ft);
435 return; 482 return;
436 } 483 }
437 484
438 /* 3. qend listing file */ 485 /* 3. qend listing file */
439 /* mm/dd/yyyy hh:mm sizesize name.ext\r\n */ 486 /* mm/dd/yyyy hh:mm sizesize name.ext\r\n */
452 499
453 read_rv = write(ft->fd, buf, ntohl(fhdr->size)); 500 read_rv = write(ft->fd, buf, ntohl(fhdr->size));
454 if (read_rv <= -1) { 501 if (read_rv <= -1) {
455 sprintf(debug_buff, "Could not send file, wrote %d\n", rcv); 502 sprintf(debug_buff, "Could not send file, wrote %d\n", rcv);
456 debug_print(debug_buff); 503 debug_print(debug_buff);
504 g_free(buf);
505 g_free(fhdr);
457 close(ft->fd); 506 close(ft->fd);
458 return; 507 free_ft(ft);
459 } 508 return;
509 }
510 g_free(buf);
460 511
461 /* 4. receive header */ 512 /* 4. receive header */
462 sprintf(debug_buff, "Receiving closing header\n"); 513 sprintf(debug_buff, "Receiving closing header\n");
463 debug_print(debug_buff); 514 debug_print(debug_buff);
464 read_rv = read(ft->fd, fhdr, 256); 515 read_rv = read_file_header(ft->fd, fhdr);
465 if (read_rv <= -1) { 516 if (read_rv <= -1) {
466 sprintf(debug_buff, "Couldn't read closing header\n"); 517 sprintf(debug_buff, "Couldn't read closing header\n");
467 debug_print(debug_buff); 518 debug_print(debug_buff);
519 g_free(fhdr);
468 close(ft->fd); 520 close(ft->fd);
521 free_ft(ft);
469 return; 522 return;
470 } 523 }
471 524
472 /* 5. wait to see if we're sending it */ 525 /* 5. wait to see if we're sending it */
473 /* read_rv = read(ft->fd, fhdr, 256); 526 fcntl(ft->fd, F_SETFL, O_NONBLOCK);
474 * if (read_rv <= -1 !! connection_is_closed()) { // uh huh 527 rcv = 0;
475 * clean_up(); 528 while (rcv != 256) {
476 * return(); 529 int i;
477 * } 530 read_rv = read_file_header(ft->fd, fhdr);
478 */ 531 if(read_rv < 0) {
532 if (errno == EWOULDBLOCK) {
533 while(gtk_events_pending())
534 gtk_main_iteration();
535 continue;
536 }
537 fclose(ft->f);
538 close(ft->fd);
539 g_free(fhdr);
540 free_ft(ft);
541 return;
542 }
543 rcv += read_rv;
544 }
479 545
480 /* 6. send the file */ 546 /* 6. send the file */
547 fw = gtk_dialog_new();
548 buf = g_malloc(2048);
549 snprintf(buf, 2048, "Sending %s to %s", fhdr->name, ft->user);
550 label = gtk_label_new(buf);
551 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->vbox), label, 0, 0, 5);
552 gtk_widget_show(label);
553 fbar = gtk_progress_bar_new();
554 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), fbar, 0, 0, 5);
555 gtk_widget_show(fbar);
556 pct = gtk_label_new("0 %");
557 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), pct, 0, 0, 5);
558 gtk_widget_show(pct);
559 button = gtk_button_new_with_label("Cancel");
560 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fw)->action_area), button, 0, 0, 5);
561 gtk_widget_show(button);
562 gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)toggle, &cont);
563 gtk_window_set_title(GTK_WINDOW(fw), "Gaim - File Transfer");
564 gtk_widget_realize(fw);
565 aol_icon(fw->window);
566 gtk_widget_show(fw);
567
568 sprintf(debug_buff, "Sending %s to %s (%d bytes)\n", fhdr->name,
569 ft->user, fhdr->totsize);
570 debug_print(debug_buff);
571
572 rcv = 0; cont = 1;
573 while (rcv != fhdr->totsize && cont) {
574 int i;
575 float pcnt = ((float)rcv)/((float)fhdr->totsize);
576 int remain = fhdr->totsize - rcv > 1024 ? 1024 : fhdr->totsize - rcv;
577 for (i = 0; i < 1024; i++)
578 fscanf(ft->f, "%c", &buf[i]);
579 read_rv = write(ft->fd, buf, remain);
580 if (read_rv < 0) {
581 if (errno == EWOULDBLOCK) {
582 while (gtk_events_pending())
583 gtk_main_iteration();
584 continue;
585 }
586 fclose(ft->f);
587 gtk_widget_destroy(fw);
588 fw = NULL;
589 fclose(ft->f);
590 close(ft->fd);
591 g_free(buf);
592 g_free(fhdr);
593 free_ft(ft);
594 return;
595 }
596 rcv += read_rv;
597 gtk_progress_bar_update(GTK_PROGRESS_BAR(fbar), pcnt);
598 sprintf(buf, "%d / %d K (%2.0f %%)", rcv/1024, ft->size/1024, 100*pcnt);
599 gtk_label_set_text(GTK_LABEL(pct), buf);
600 while(gtk_events_pending())
601 gtk_main_iteration();
602 }
603 fclose(ft->f);
604 gtk_widget_destroy(fw);
605 fw = NULL;
606
607 if (!cont) {
608 char *tmp = frombase64(ft->cookie);
609 sprintf(buf, "toc_rvous_cancel %s %s %s", ft->user, tmp, ft->UID);
610 sflap_send(buf, strlen(buf), TYPE_DATA);
611 g_free(buf);
612 close(ft->fd);
613 free_ft(ft);
614 g_free(fhdr);
615 return;
616 }
617
618 sprintf(debug_buff, "Upload complete.\n");
619 debug_print(debug_buff);
481 620
482 /* 7. receive closing header */ 621 /* 7. receive closing header */
483 622
484 /* done */ 623 /* done */
624 close(ft->fd);
625 g_free(buf);
626 g_free(fhdr);
627 free_ft(ft);
485 } 628 }
486 629
487 void accept_file_dialog(struct file_transfer *ft) 630 void accept_file_dialog(struct file_transfer *ft)
488 { 631 {
489 GtkWidget *accept, *info, *warn, *cancel; 632 GtkWidget *accept, *info, *warn, *cancel;