ftp.c revision 103423
1/* 2 * Copyright (c) 1985, 1989, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include "ftp_locl.h" 35RCSID ("$Id: ftp.c,v 1.74 2002/09/04 22:00:12 joda Exp $"); 36 37struct sockaddr_storage hisctladdr_ss; 38struct sockaddr *hisctladdr = (struct sockaddr *)&hisctladdr_ss; 39struct sockaddr_storage data_addr_ss; 40struct sockaddr *data_addr = (struct sockaddr *)&data_addr_ss; 41struct sockaddr_storage myctladdr_ss; 42struct sockaddr *myctladdr = (struct sockaddr *)&myctladdr_ss; 43int data = -1; 44int abrtflag = 0; 45jmp_buf ptabort; 46int ptabflg; 47int ptflag = 0; 48off_t restart_point = 0; 49 50 51FILE *cin, *cout; 52 53typedef void (*sighand) (int); 54 55char * 56hookup (const char *host, int port) 57{ 58 static char hostnamebuf[MaxHostNameLen]; 59 struct addrinfo *ai, *a; 60 struct addrinfo hints; 61 int error; 62 char portstr[NI_MAXSERV]; 63 socklen_t len; 64 int s; 65 66 memset (&hints, 0, sizeof(hints)); 67 hints.ai_socktype = SOCK_STREAM; 68 hints.ai_protocol = IPPROTO_TCP; 69 hints.ai_flags = AI_CANONNAME; 70 71 snprintf (portstr, sizeof(portstr), "%u", ntohs(port)); 72 73 error = getaddrinfo (host, portstr, &hints, &ai); 74 if (error) { 75 warnx ("%s: %s", host, gai_strerror(error)); 76 code = -1; 77 return NULL; 78 } 79 strlcpy (hostnamebuf, host, sizeof(hostnamebuf)); 80 hostname = hostnamebuf; 81 82 for (a = ai; a != NULL; a = a->ai_next) { 83 s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); 84 if (s < 0) 85 continue; 86 87 if (a->ai_canonname != NULL) 88 strlcpy (hostnamebuf, a->ai_canonname, sizeof(hostnamebuf)); 89 90 memcpy (hisctladdr, a->ai_addr, a->ai_addrlen); 91 92 error = connect (s, a->ai_addr, a->ai_addrlen); 93 if (error < 0) { 94 char addrstr[256]; 95 96 if (getnameinfo (a->ai_addr, a->ai_addrlen, 97 addrstr, sizeof(addrstr), 98 NULL, 0, NI_NUMERICHOST) != 0) 99 strlcpy (addrstr, "unknown address", sizeof(addrstr)); 100 101 warn ("connect %s", addrstr); 102 close (s); 103 continue; 104 } 105 break; 106 } 107 freeaddrinfo (ai); 108 if (error < 0) { 109 warnx ("failed to contact %s", host); 110 code = -1; 111 return NULL; 112 } 113 114 len = sizeof(myctladdr_ss); 115 if (getsockname (s, myctladdr, &len) < 0) { 116 warn ("getsockname"); 117 code = -1; 118 close (s); 119 return NULL; 120 } 121#ifdef IPTOS_LOWDELAY 122 socket_set_tos (s, IPTOS_LOWDELAY); 123#endif 124 cin = fdopen (s, "r"); 125 cout = fdopen (s, "w"); 126 if (cin == NULL || cout == NULL) { 127 warnx ("fdopen failed."); 128 if (cin) 129 fclose (cin); 130 if (cout) 131 fclose (cout); 132 code = -1; 133 goto bad; 134 } 135 if (verbose) 136 printf ("Connected to %s.\n", hostname); 137 if (getreply (0) > 2) { /* read startup message from server */ 138 if (cin) 139 fclose (cin); 140 if (cout) 141 fclose (cout); 142 code = -1; 143 goto bad; 144 } 145#if defined(SO_OOBINLINE) && defined(HAVE_SETSOCKOPT) 146 { 147 int on = 1; 148 149 if (setsockopt (s, SOL_SOCKET, SO_OOBINLINE, (char *) &on, sizeof (on)) 150 < 0 && debug) { 151 warn ("setsockopt"); 152 } 153 } 154#endif /* SO_OOBINLINE */ 155 156 return (hostname); 157bad: 158 close (s); 159 return NULL; 160} 161 162int 163login (char *host) 164{ 165 char tmp[80]; 166 char defaultpass[128]; 167 char *user, *pass, *acct; 168 int n, aflag = 0; 169 170 char *myname = NULL; 171 struct passwd *pw = k_getpwuid(getuid()); 172 173 if (pw != NULL) 174 myname = pw->pw_name; 175 176 user = pass = acct = 0; 177 178 if(sec_login(host)) 179 printf("\n*** Using plaintext user and password ***\n\n"); 180 else{ 181 printf("Authentication successful.\n\n"); 182 } 183 184 if (ruserpass (host, &user, &pass, &acct) < 0) { 185 code = -1; 186 return (0); 187 } 188 while (user == NULL) { 189 if (myname) 190 printf ("Name (%s:%s): ", host, myname); 191 else 192 printf ("Name (%s): ", host); 193 *tmp = '\0'; 194 if (fgets (tmp, sizeof (tmp) - 1, stdin) != NULL) 195 tmp[strlen (tmp) - 1] = '\0'; 196 if (*tmp == '\0') 197 user = myname; 198 else 199 user = tmp; 200 } 201 strlcpy(username, user, sizeof(username)); 202 n = command("USER %s", user); 203 if (n == COMPLETE) 204 n = command("PASS dummy"); /* DK: Compatibility with gssftp daemon */ 205 else if(n == CONTINUE) { 206 if (pass == NULL) { 207 char prompt[128]; 208 if(myname && 209 (!strcmp(user, "ftp") || !strcmp(user, "anonymous"))) { 210 snprintf(defaultpass, sizeof(defaultpass), 211 "%s@%s", myname, mydomain); 212 snprintf(prompt, sizeof(prompt), 213 "Password (%s): ", defaultpass); 214 } else if (sec_complete) { 215 pass = myname; 216 } else { 217 *defaultpass = '\0'; 218 snprintf(prompt, sizeof(prompt), "Password: "); 219 } 220 if (pass == NULL) { 221 pass = defaultpass; 222 des_read_pw_string (tmp, sizeof (tmp), prompt, 0); 223 if (tmp[0]) 224 pass = tmp; 225 } 226 } 227 n = command ("PASS %s", pass); 228 } 229 if (n == CONTINUE) { 230 aflag++; 231 acct = tmp; 232 des_read_pw_string (acct, 128, "Account:", 0); 233 n = command ("ACCT %s", acct); 234 } 235 if (n != COMPLETE) { 236 warnx ("Login failed."); 237 return (0); 238 } 239 if (!aflag && acct != NULL) 240 command ("ACCT %s", acct); 241 if (proxy) 242 return (1); 243 for (n = 0; n < macnum; ++n) { 244 if (!strcmp("init", macros[n].mac_name)) { 245 strlcpy (line, "$init", sizeof (line)); 246 makeargv(); 247 domacro(margc, margv); 248 break; 249 } 250 } 251 sec_set_protection_level (); 252 return (1); 253} 254 255void 256cmdabort (int sig) 257{ 258 259 printf ("\n"); 260 fflush (stdout); 261 abrtflag++; 262 if (ptflag) 263 longjmp (ptabort, 1); 264} 265 266int 267command (char *fmt,...) 268{ 269 va_list ap; 270 int r; 271 sighand oldintr; 272 273 abrtflag = 0; 274 if (cout == NULL) { 275 warn ("No control connection for command"); 276 code = -1; 277 return (0); 278 } 279 oldintr = signal(SIGINT, cmdabort); 280 if(debug){ 281 printf("---> "); 282 if (strncmp("PASS ", fmt, 5) == 0) 283 printf("PASS XXXX"); 284 else { 285 va_start(ap, fmt); 286 vfprintf(stdout, fmt, ap); 287 va_end(ap); 288 } 289 } 290 va_start(ap, fmt); 291 sec_vfprintf(cout, fmt, ap); 292 va_end(ap); 293 if(debug){ 294 printf("\n"); 295 fflush(stdout); 296 } 297 fprintf (cout, "\r\n"); 298 fflush (cout); 299 cpend = 1; 300 r = getreply (!strcmp (fmt, "QUIT")); 301 if (abrtflag && oldintr != SIG_IGN) 302 (*oldintr) (SIGINT); 303 signal (SIGINT, oldintr); 304 return (r); 305} 306 307char reply_string[BUFSIZ]; /* last line of previous reply */ 308 309int 310getreply (int expecteof) 311{ 312 char *p; 313 char *lead_string; 314 int c; 315 struct sigaction sa, osa; 316 char buf[8192]; 317 int reply_code; 318 int long_warn = 0; 319 320 sigemptyset (&sa.sa_mask); 321 sa.sa_flags = 0; 322 sa.sa_handler = cmdabort; 323 sigaction (SIGINT, &sa, &osa); 324 325 p = buf; 326 327 reply_code = 0; 328 while (1) { 329 c = getc (cin); 330 switch (c) { 331 case EOF: 332 if (expecteof) { 333 sigaction (SIGINT, &osa, NULL); 334 code = 221; 335 return 0; 336 } 337 lostpeer (0); 338 if (verbose) { 339 printf ("421 Service not available, " 340 "remote server has closed connection\n"); 341 fflush (stdout); 342 } 343 code = 421; 344 return (4); 345 case IAC: 346 c = getc (cin); 347 if (c == WILL || c == WONT) 348 fprintf (cout, "%c%c%c", IAC, DONT, getc (cin)); 349 if (c == DO || c == DONT) 350 fprintf (cout, "%c%c%c", IAC, WONT, getc (cin)); 351 continue; 352 case '\n': 353 *p++ = '\0'; 354 if(isdigit(buf[0])){ 355 sscanf(buf, "%d", &code); 356 if(code == 631){ 357 code = 0; 358 sec_read_msg(buf, prot_safe); 359 sscanf(buf, "%d", &code); 360 lead_string = "S:"; 361 } else if(code == 632){ 362 code = 0; 363 sec_read_msg(buf, prot_private); 364 sscanf(buf, "%d", &code); 365 lead_string = "P:"; 366 }else if(code == 633){ 367 code = 0; 368 sec_read_msg(buf, prot_confidential); 369 sscanf(buf, "%d", &code); 370 lead_string = "C:"; 371 }else if(sec_complete) 372 lead_string = "!!"; 373 else 374 lead_string = ""; 375 if(code != 0 && reply_code == 0) 376 reply_code = code; 377 if (verbose > 0 || (verbose > -1 && code > 499)) 378 fprintf (stdout, "%s%s\n", lead_string, buf); 379 if (code == reply_code && buf[3] == ' ') { 380 strlcpy (reply_string, buf, sizeof(reply_string)); 381 if (code >= 200) 382 cpend = 0; 383 sigaction (SIGINT, &osa, NULL); 384 if (code == 421) 385 lostpeer (0); 386#if 1 387 if (abrtflag && 388 osa.sa_handler != cmdabort && 389 osa.sa_handler != SIG_IGN) 390 osa.sa_handler (SIGINT); 391#endif 392 if (code == 227 || code == 229) { 393 char *p; 394 395 p = strchr (reply_string, '('); 396 if (p) { 397 p++; 398 strlcpy(pasv, p, sizeof(pasv)); 399 } 400 } 401 return code / 100; 402 } 403 }else{ 404 if(verbose > 0 || (verbose > -1 && code > 499)){ 405 if(sec_complete) 406 fprintf(stdout, "!!"); 407 fprintf(stdout, "%s\n", buf); 408 } 409 } 410 p = buf; 411 long_warn = 0; 412 continue; 413 default: 414 if(p < buf + sizeof(buf) - 1) 415 *p++ = c; 416 else if(long_warn == 0) { 417 fprintf(stderr, "WARNING: incredibly long line received\n"); 418 long_warn = 1; 419 } 420 } 421 } 422 423} 424 425 426#if 0 427int 428getreply (int expecteof) 429{ 430 int c, n; 431 int dig; 432 int originalcode = 0, continuation = 0; 433 sighand oldintr; 434 int pflag = 0; 435 char *cp, *pt = pasv; 436 437 oldintr = signal (SIGINT, cmdabort); 438 for (;;) { 439 dig = n = code = 0; 440 cp = reply_string; 441 while ((c = getc (cin)) != '\n') { 442 if (c == IAC) { /* handle telnet commands */ 443 switch (c = getc (cin)) { 444 case WILL: 445 case WONT: 446 c = getc (cin); 447 fprintf (cout, "%c%c%c", IAC, DONT, c); 448 fflush (cout); 449 break; 450 case DO: 451 case DONT: 452 c = getc (cin); 453 fprintf (cout, "%c%c%c", IAC, WONT, c); 454 fflush (cout); 455 break; 456 default: 457 break; 458 } 459 continue; 460 } 461 dig++; 462 if (c == EOF) { 463 if (expecteof) { 464 signal (SIGINT, oldintr); 465 code = 221; 466 return (0); 467 } 468 lostpeer (0); 469 if (verbose) { 470 printf ("421 Service not available, remote server has closed connection\n"); 471 fflush (stdout); 472 } 473 code = 421; 474 return (4); 475 } 476 if (c != '\r' && (verbose > 0 || 477 (verbose > -1 && n == '5' && dig > 4))) { 478 if (proxflag && 479 (dig == 1 || dig == 5 && verbose == 0)) 480 printf ("%s:", hostname); 481 putchar (c); 482 } 483 if (dig < 4 && isdigit (c)) 484 code = code * 10 + (c - '0'); 485 if (!pflag && code == 227) 486 pflag = 1; 487 if (dig > 4 && pflag == 1 && isdigit (c)) 488 pflag = 2; 489 if (pflag == 2) { 490 if (c != '\r' && c != ')') 491 *pt++ = c; 492 else { 493 *pt = '\0'; 494 pflag = 3; 495 } 496 } 497 if (dig == 4 && c == '-') { 498 if (continuation) 499 code = 0; 500 continuation++; 501 } 502 if (n == 0) 503 n = c; 504 if (cp < &reply_string[sizeof (reply_string) - 1]) 505 *cp++ = c; 506 } 507 if (verbose > 0 || verbose > -1 && n == '5') { 508 putchar (c); 509 fflush (stdout); 510 } 511 if (continuation && code != originalcode) { 512 if (originalcode == 0) 513 originalcode = code; 514 continue; 515 } 516 *cp = '\0'; 517 if(sec_complete){ 518 if(code == 631) 519 sec_read_msg(reply_string, prot_safe); 520 else if(code == 632) 521 sec_read_msg(reply_string, prot_private); 522 else if(code == 633) 523 sec_read_msg(reply_string, prot_confidential); 524 n = code / 100 + '0'; 525 } 526 if (n != '1') 527 cpend = 0; 528 signal (SIGINT, oldintr); 529 if (code == 421 || originalcode == 421) 530 lostpeer (0); 531 if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN) 532 (*oldintr) (SIGINT); 533 return (n - '0'); 534 } 535} 536 537#endif 538 539int 540empty (fd_set * mask, int sec) 541{ 542 struct timeval t; 543 544 t.tv_sec = sec; 545 t.tv_usec = 0; 546 return (select (FD_SETSIZE, mask, NULL, NULL, &t)); 547} 548 549jmp_buf sendabort; 550 551static RETSIGTYPE 552abortsend (int sig) 553{ 554 555 mflag = 0; 556 abrtflag = 0; 557 printf ("\nsend aborted\nwaiting for remote to finish abort\n"); 558 fflush (stdout); 559 longjmp (sendabort, 1); 560} 561 562#define HASHBYTES 1024 563 564static int 565copy_stream (FILE * from, FILE * to) 566{ 567 static size_t bufsize; 568 static char *buf; 569 int n; 570 int bytes = 0; 571 int werr = 0; 572 int hashbytes = HASHBYTES; 573 struct stat st; 574 575#if defined(HAVE_MMAP) && !defined(NO_MMAP) 576 void *chunk; 577 578#ifndef MAP_FAILED 579#define MAP_FAILED (-1) 580#endif 581 582 if (fstat (fileno (from), &st) == 0 && S_ISREG (st.st_mode)) { 583 /* 584 * mmap zero bytes has potential of loosing, don't do it. 585 */ 586 if (st.st_size == 0) 587 return 0; 588 chunk = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fileno (from), 0); 589 if (chunk != (void *) MAP_FAILED) { 590 int res; 591 592 res = sec_write (fileno (to), chunk, st.st_size); 593 if (munmap (chunk, st.st_size) < 0) 594 warn ("munmap"); 595 sec_fflush (to); 596 return res; 597 } 598 } 599#endif 600 601 buf = alloc_buffer (buf, &bufsize, 602 fstat (fileno (from), &st) >= 0 ? &st : NULL); 603 if (buf == NULL) 604 return -1; 605 606 while ((n = read (fileno (from), buf, bufsize)) > 0) { 607 werr = sec_write (fileno (to), buf, n); 608 if (werr < 0) 609 break; 610 bytes += werr; 611 while (hash && bytes > hashbytes) { 612 putchar ('#'); 613 hashbytes += HASHBYTES; 614 } 615 } 616 sec_fflush (to); 617 if (n < 0) 618 warn ("local"); 619 620 if (werr < 0) { 621 if (errno != EPIPE) 622 warn ("netout"); 623 bytes = -1; 624 } 625 return bytes; 626} 627 628void 629sendrequest (char *cmd, char *local, char *remote, char *lmode, int printnames) 630{ 631 struct stat st; 632 struct timeval start, stop; 633 int c, d; 634 FILE *fin, *dout = 0; 635 int (*closefunc) (FILE *); 636 RETSIGTYPE (*oldintr)(int), (*oldintp)(int); 637 long bytes = 0, hashbytes = HASHBYTES; 638 char *rmode = "w"; 639 640 if (verbose && printnames) { 641 if (local && strcmp (local, "-") != 0) 642 printf ("local: %s ", local); 643 if (remote) 644 printf ("remote: %s\n", remote); 645 } 646 if (proxy) { 647 proxtrans (cmd, local, remote); 648 return; 649 } 650 if (curtype != type) 651 changetype (type, 0); 652 closefunc = NULL; 653 oldintr = NULL; 654 oldintp = NULL; 655 656 if (setjmp (sendabort)) { 657 while (cpend) { 658 getreply (0); 659 } 660 if (data >= 0) { 661 close (data); 662 data = -1; 663 } 664 if (oldintr) 665 signal (SIGINT, oldintr); 666 if (oldintp) 667 signal (SIGPIPE, oldintp); 668 code = -1; 669 return; 670 } 671 oldintr = signal (SIGINT, abortsend); 672 if (strcmp (local, "-") == 0) 673 fin = stdin; 674 else if (*local == '|') { 675 oldintp = signal (SIGPIPE, SIG_IGN); 676 fin = popen (local + 1, lmode); 677 if (fin == NULL) { 678 warn ("%s", local + 1); 679 signal (SIGINT, oldintr); 680 signal (SIGPIPE, oldintp); 681 code = -1; 682 return; 683 } 684 closefunc = pclose; 685 } else { 686 fin = fopen (local, lmode); 687 if (fin == NULL) { 688 warn ("local: %s", local); 689 signal (SIGINT, oldintr); 690 code = -1; 691 return; 692 } 693 closefunc = fclose; 694 if (fstat (fileno (fin), &st) < 0 || 695 (st.st_mode & S_IFMT) != S_IFREG) { 696 fprintf (stdout, "%s: not a plain file.\n", local); 697 signal (SIGINT, oldintr); 698 fclose (fin); 699 code = -1; 700 return; 701 } 702 } 703 if (initconn ()) { 704 signal (SIGINT, oldintr); 705 if (oldintp) 706 signal (SIGPIPE, oldintp); 707 code = -1; 708 if (closefunc != NULL) 709 (*closefunc) (fin); 710 return; 711 } 712 if (setjmp (sendabort)) 713 goto abort; 714 715 if (restart_point && 716 (strcmp (cmd, "STOR") == 0 || strcmp (cmd, "APPE") == 0)) { 717 int rc; 718 719 switch (curtype) { 720 case TYPE_A: 721 rc = fseek (fin, (long) restart_point, SEEK_SET); 722 break; 723 case TYPE_I: 724 case TYPE_L: 725 rc = lseek (fileno (fin), restart_point, SEEK_SET); 726 break; 727 } 728 if (rc < 0) { 729 warn ("local: %s", local); 730 restart_point = 0; 731 if (closefunc != NULL) 732 (*closefunc) (fin); 733 return; 734 } 735 if (command ("REST %ld", (long) restart_point) 736 != CONTINUE) { 737 restart_point = 0; 738 if (closefunc != NULL) 739 (*closefunc) (fin); 740 return; 741 } 742 restart_point = 0; 743 rmode = "r+w"; 744 } 745 if (remote) { 746 if (command ("%s %s", cmd, remote) != PRELIM) { 747 signal (SIGINT, oldintr); 748 if (oldintp) 749 signal (SIGPIPE, oldintp); 750 if (closefunc != NULL) 751 (*closefunc) (fin); 752 return; 753 } 754 } else if (command ("%s", cmd) != PRELIM) { 755 signal(SIGINT, oldintr); 756 if (oldintp) 757 signal(SIGPIPE, oldintp); 758 if (closefunc != NULL) 759 (*closefunc)(fin); 760 return; 761 } 762 dout = dataconn(rmode); 763 if (dout == NULL) 764 goto abort; 765 set_buffer_size (fileno (dout), 0); 766 gettimeofday (&start, (struct timezone *) 0); 767 oldintp = signal (SIGPIPE, SIG_IGN); 768 switch (curtype) { 769 770 case TYPE_I: 771 case TYPE_L: 772 errno = d = c = 0; 773 bytes = copy_stream (fin, dout); 774 break; 775 776 case TYPE_A: 777 while ((c = getc (fin)) != EOF) { 778 if (c == '\n') { 779 while (hash && (bytes >= hashbytes)) { 780 putchar ('#'); 781 fflush (stdout); 782 hashbytes += HASHBYTES; 783 } 784 if (ferror (dout)) 785 break; 786 sec_putc ('\r', dout); 787 bytes++; 788 } 789 sec_putc (c, dout); 790 bytes++; 791 } 792 sec_fflush (dout); 793 if (hash) { 794 if (bytes < hashbytes) 795 putchar ('#'); 796 putchar ('\n'); 797 fflush (stdout); 798 } 799 if (ferror (fin)) 800 warn ("local: %s", local); 801 if (ferror (dout)) { 802 if (errno != EPIPE) 803 warn ("netout"); 804 bytes = -1; 805 } 806 break; 807 } 808 if (closefunc != NULL) 809 (*closefunc) (fin); 810 fclose (dout); 811 gettimeofday (&stop, (struct timezone *) 0); 812 getreply (0); 813 signal (SIGINT, oldintr); 814 if (oldintp) 815 signal (SIGPIPE, oldintp); 816 if (bytes > 0) 817 ptransfer ("sent", bytes, &start, &stop); 818 return; 819abort: 820 signal (SIGINT, oldintr); 821 if (oldintp) 822 signal (SIGPIPE, oldintp); 823 if (!cpend) { 824 code = -1; 825 return; 826 } 827 if (data >= 0) { 828 close (data); 829 data = -1; 830 } 831 if (dout) 832 fclose (dout); 833 getreply (0); 834 code = -1; 835 if (closefunc != NULL && fin != NULL) 836 (*closefunc) (fin); 837 gettimeofday (&stop, (struct timezone *) 0); 838 if (bytes > 0) 839 ptransfer ("sent", bytes, &start, &stop); 840} 841 842jmp_buf recvabort; 843 844void 845abortrecv (int sig) 846{ 847 848 mflag = 0; 849 abrtflag = 0; 850 printf ("\nreceive aborted\nwaiting for remote to finish abort\n"); 851 fflush (stdout); 852 longjmp (recvabort, 1); 853} 854 855void 856recvrequest (char *cmd, char *local, char *remote, 857 char *lmode, int printnames, int local_given) 858{ 859 FILE *fout, *din = 0; 860 int (*closefunc) (FILE *); 861 sighand oldintr, oldintp; 862 int c, d, is_retr, tcrflag, bare_lfs = 0; 863 static size_t bufsize; 864 static char *buf; 865 long bytes = 0, hashbytes = HASHBYTES; 866 struct timeval start, stop; 867 struct stat st; 868 869 is_retr = strcmp (cmd, "RETR") == 0; 870 if (is_retr && verbose && printnames) { 871 if (local && strcmp (local, "-") != 0) 872 printf ("local: %s ", local); 873 if (remote) 874 printf ("remote: %s\n", remote); 875 } 876 if (proxy && is_retr) { 877 proxtrans (cmd, local, remote); 878 return; 879 } 880 closefunc = NULL; 881 oldintr = NULL; 882 oldintp = NULL; 883 tcrflag = !crflag && is_retr; 884 if (setjmp (recvabort)) { 885 while (cpend) { 886 getreply (0); 887 } 888 if (data >= 0) { 889 close (data); 890 data = -1; 891 } 892 if (oldintr) 893 signal (SIGINT, oldintr); 894 code = -1; 895 return; 896 } 897 oldintr = signal (SIGINT, abortrecv); 898 if (!local_given || (strcmp (local, "-") && *local != '|')) { 899 if (access (local, 2) < 0) { 900 char *dir = strrchr (local, '/'); 901 902 if (errno != ENOENT && errno != EACCES) { 903 warn ("local: %s", local); 904 signal (SIGINT, oldintr); 905 code = -1; 906 return; 907 } 908 if (dir != NULL) 909 *dir = 0; 910 d = access (dir ? local : ".", 2); 911 if (dir != NULL) 912 *dir = '/'; 913 if (d < 0) { 914 warn ("local: %s", local); 915 signal (SIGINT, oldintr); 916 code = -1; 917 return; 918 } 919 if (!runique && errno == EACCES && 920 chmod (local, 0600) < 0) { 921 warn ("local: %s", local); 922 signal (SIGINT, oldintr); 923 signal (SIGINT, oldintr); 924 code = -1; 925 return; 926 } 927 if (runique && errno == EACCES && 928 (local = gunique (local)) == NULL) { 929 signal (SIGINT, oldintr); 930 code = -1; 931 return; 932 } 933 } else if (runique && (local = gunique (local)) == NULL) { 934 signal(SIGINT, oldintr); 935 code = -1; 936 return; 937 } 938 } 939 if (!is_retr) { 940 if (curtype != TYPE_A) 941 changetype (TYPE_A, 0); 942 } else if (curtype != type) 943 changetype (type, 0); 944 if (initconn ()) { 945 signal (SIGINT, oldintr); 946 code = -1; 947 return; 948 } 949 if (setjmp (recvabort)) 950 goto abort; 951 if (is_retr && restart_point && 952 command ("REST %ld", (long) restart_point) != CONTINUE) 953 return; 954 if (remote) { 955 if (command ("%s %s", cmd, remote) != PRELIM) { 956 signal (SIGINT, oldintr); 957 return; 958 } 959 } else { 960 if (command ("%s", cmd) != PRELIM) { 961 signal (SIGINT, oldintr); 962 return; 963 } 964 } 965 din = dataconn ("r"); 966 if (din == NULL) 967 goto abort; 968 set_buffer_size (fileno (din), 1); 969 if (local_given && strcmp (local, "-") == 0) 970 fout = stdout; 971 else if (local_given && *local == '|') { 972 oldintp = signal (SIGPIPE, SIG_IGN); 973 fout = popen (local + 1, "w"); 974 if (fout == NULL) { 975 warn ("%s", local + 1); 976 goto abort; 977 } 978 closefunc = pclose; 979 } else { 980 fout = fopen (local, lmode); 981 if (fout == NULL) { 982 warn ("local: %s", local); 983 goto abort; 984 } 985 closefunc = fclose; 986 } 987 buf = alloc_buffer (buf, &bufsize, 988 fstat (fileno (fout), &st) >= 0 ? &st : NULL); 989 if (buf == NULL) 990 goto abort; 991 992 gettimeofday (&start, (struct timezone *) 0); 993 switch (curtype) { 994 995 case TYPE_I: 996 case TYPE_L: 997 if (restart_point && 998 lseek (fileno (fout), restart_point, SEEK_SET) < 0) { 999 warn ("local: %s", local); 1000 if (closefunc != NULL) 1001 (*closefunc) (fout); 1002 return; 1003 } 1004 errno = d = 0; 1005 while ((c = sec_read (fileno (din), buf, bufsize)) > 0) { 1006 if ((d = write (fileno (fout), buf, c)) != c) 1007 break; 1008 bytes += c; 1009 if (hash) { 1010 while (bytes >= hashbytes) { 1011 putchar ('#'); 1012 hashbytes += HASHBYTES; 1013 } 1014 fflush (stdout); 1015 } 1016 } 1017 if (hash && bytes > 0) { 1018 if (bytes < HASHBYTES) 1019 putchar ('#'); 1020 putchar ('\n'); 1021 fflush (stdout); 1022 } 1023 if (c < 0) { 1024 if (errno != EPIPE) 1025 warn ("netin"); 1026 bytes = -1; 1027 } 1028 if (d < c) { 1029 if (d < 0) 1030 warn ("local: %s", local); 1031 else 1032 warnx ("%s: short write", local); 1033 } 1034 break; 1035 1036 case TYPE_A: 1037 if (restart_point) { 1038 int i, n, ch; 1039 1040 if (fseek (fout, 0L, SEEK_SET) < 0) 1041 goto done; 1042 n = restart_point; 1043 for (i = 0; i++ < n;) { 1044 if ((ch = sec_getc (fout)) == EOF) 1045 goto done; 1046 if (ch == '\n') 1047 i++; 1048 } 1049 if (fseek (fout, 0L, SEEK_CUR) < 0) { 1050 done: 1051 warn ("local: %s", local); 1052 if (closefunc != NULL) 1053 (*closefunc) (fout); 1054 return; 1055 } 1056 } 1057 while ((c = sec_getc(din)) != EOF) { 1058 if (c == '\n') 1059 bare_lfs++; 1060 while (c == '\r') { 1061 while (hash && (bytes >= hashbytes)) { 1062 putchar ('#'); 1063 fflush (stdout); 1064 hashbytes += HASHBYTES; 1065 } 1066 bytes++; 1067 if ((c = sec_getc (din)) != '\n' || tcrflag) { 1068 if (ferror (fout)) 1069 goto break2; 1070 putc ('\r', fout); 1071 if (c == '\0') { 1072 bytes++; 1073 goto contin2; 1074 } 1075 if (c == EOF) 1076 goto contin2; 1077 } 1078 } 1079 putc (c, fout); 1080 bytes++; 1081 contin2:; 1082 } 1083break2: 1084 if (bare_lfs) { 1085 printf ("WARNING! %d bare linefeeds received in ASCII mode\n", 1086 bare_lfs); 1087 printf ("File may not have transferred correctly.\n"); 1088 } 1089 if (hash) { 1090 if (bytes < hashbytes) 1091 putchar ('#'); 1092 putchar ('\n'); 1093 fflush (stdout); 1094 } 1095 if (ferror (din)) { 1096 if (errno != EPIPE) 1097 warn ("netin"); 1098 bytes = -1; 1099 } 1100 if (ferror (fout)) 1101 warn ("local: %s", local); 1102 break; 1103 } 1104 if (closefunc != NULL) 1105 (*closefunc) (fout); 1106 signal (SIGINT, oldintr); 1107 if (oldintp) 1108 signal (SIGPIPE, oldintp); 1109 fclose (din); 1110 gettimeofday (&stop, (struct timezone *) 0); 1111 getreply (0); 1112 if (bytes > 0 && is_retr) 1113 ptransfer ("received", bytes, &start, &stop); 1114 return; 1115abort: 1116 1117 /* abort using RFC959 recommended IP,SYNC sequence */ 1118 1119 if (oldintp) 1120 signal (SIGPIPE, oldintr); 1121 signal (SIGINT, SIG_IGN); 1122 if (!cpend) { 1123 code = -1; 1124 signal (SIGINT, oldintr); 1125 return; 1126 } 1127 abort_remote(din); 1128 code = -1; 1129 if (data >= 0) { 1130 close (data); 1131 data = -1; 1132 } 1133 if (closefunc != NULL && fout != NULL) 1134 (*closefunc) (fout); 1135 if (din) 1136 fclose (din); 1137 gettimeofday (&stop, (struct timezone *) 0); 1138 if (bytes > 0) 1139 ptransfer ("received", bytes, &start, &stop); 1140 signal (SIGINT, oldintr); 1141} 1142 1143static int 1144parse_epsv (const char *str) 1145{ 1146 char sep; 1147 char *end; 1148 int port; 1149 1150 if (*str == '\0') 1151 return -1; 1152 sep = *str++; 1153 if (sep != *str++) 1154 return -1; 1155 if (sep != *str++) 1156 return -1; 1157 port = strtol (str, &end, 0); 1158 if (str == end) 1159 return -1; 1160 if (end[0] != sep || end[1] != '\0') 1161 return -1; 1162 return htons(port); 1163} 1164 1165static int 1166parse_pasv (struct sockaddr_in *sin, const char *str) 1167{ 1168 int a0, a1, a2, a3, p0, p1; 1169 1170 /* 1171 * What we've got at this point is a string of comma separated 1172 * one-byte unsigned integer values. The first four are the an IP 1173 * address. The fifth is the MSB of the port number, the sixth is the 1174 * LSB. From that we'll prepare a sockaddr_in. 1175 */ 1176 1177 if (sscanf (str, "%d,%d,%d,%d,%d,%d", 1178 &a0, &a1, &a2, &a3, &p0, &p1) != 6) { 1179 printf ("Passive mode address scan failure. " 1180 "Shouldn't happen!\n"); 1181 return -1; 1182 } 1183 if (a0 < 0 || a0 > 255 || 1184 a1 < 0 || a1 > 255 || 1185 a2 < 0 || a2 > 255 || 1186 a3 < 0 || a3 > 255 || 1187 p0 < 0 || p0 > 255 || 1188 p1 < 0 || p1 > 255) { 1189 printf ("Can't parse passive mode string.\n"); 1190 return -1; 1191 } 1192 memset (sin, 0, sizeof(*sin)); 1193 sin->sin_family = AF_INET; 1194 sin->sin_addr.s_addr = htonl ((a0 << 24) | (a1 << 16) | 1195 (a2 << 8) | a3); 1196 sin->sin_port = htons ((p0 << 8) | p1); 1197 return 0; 1198} 1199 1200static int 1201passive_mode (void) 1202{ 1203 int port; 1204 1205 data = socket (myctladdr->sa_family, SOCK_STREAM, 0); 1206 if (data < 0) { 1207 warn ("socket"); 1208 return (1); 1209 } 1210 if (options & SO_DEBUG) 1211 socket_set_debug (data); 1212 if (command ("EPSV") != COMPLETE) { 1213 if (command ("PASV") != COMPLETE) { 1214 printf ("Passive mode refused.\n"); 1215 goto bad; 1216 } 1217 } 1218 1219 /* 1220 * Parse the reply to EPSV or PASV 1221 */ 1222 1223 port = parse_epsv (pasv); 1224 if (port > 0) { 1225 data_addr->sa_family = myctladdr->sa_family; 1226 socket_set_address_and_port (data_addr, 1227 socket_get_address (hisctladdr), 1228 port); 1229 } else { 1230 if (parse_pasv ((struct sockaddr_in *)data_addr, pasv) < 0) 1231 goto bad; 1232 } 1233 1234 if (connect (data, data_addr, socket_sockaddr_size (data_addr)) < 0) { 1235 warn ("connect"); 1236 goto bad; 1237 } 1238#ifdef IPTOS_THROUGHPUT 1239 socket_set_tos (data, IPTOS_THROUGHPUT); 1240#endif 1241 return (0); 1242bad: 1243 close (data); 1244 data = -1; 1245 sendport = 1; 1246 return (1); 1247} 1248 1249 1250static int 1251active_mode (void) 1252{ 1253 int tmpno = 0; 1254 socklen_t len; 1255 int result; 1256 1257noport: 1258 data_addr->sa_family = myctladdr->sa_family; 1259 socket_set_address_and_port (data_addr, socket_get_address (myctladdr), 1260 sendport ? 0 : socket_get_port (myctladdr)); 1261 1262 if (data != -1) 1263 close (data); 1264 data = socket (data_addr->sa_family, SOCK_STREAM, 0); 1265 if (data < 0) { 1266 warn ("socket"); 1267 if (tmpno) 1268 sendport = 1; 1269 return (1); 1270 } 1271 if (!sendport) 1272 socket_set_reuseaddr (data, 1); 1273 if (bind (data, data_addr, socket_sockaddr_size (data_addr)) < 0) { 1274 warn ("bind"); 1275 goto bad; 1276 } 1277 if (options & SO_DEBUG) 1278 socket_set_debug (data); 1279 len = sizeof (data_addr_ss); 1280 if (getsockname (data, data_addr, &len) < 0) { 1281 warn ("getsockname"); 1282 goto bad; 1283 } 1284 if (listen (data, 1) < 0) 1285 warn ("listen"); 1286 if (sendport) { 1287 char addr_str[256]; 1288 int inet_af; 1289 int overbose; 1290 1291 if (inet_ntop (data_addr->sa_family, socket_get_address (data_addr), 1292 addr_str, sizeof(addr_str)) == NULL) 1293 errx (1, "inet_ntop failed"); 1294 switch (data_addr->sa_family) { 1295 case AF_INET : 1296 inet_af = 1; 1297 break; 1298#ifdef HAVE_IPV6 1299 case AF_INET6 : 1300 inet_af = 2; 1301 break; 1302#endif 1303 default : 1304 errx (1, "bad address family %d", data_addr->sa_family); 1305 } 1306 1307 1308 overbose = verbose; 1309 if (debug == 0) 1310 verbose = -1; 1311 1312 result = command ("EPRT |%d|%s|%d|", 1313 inet_af, addr_str, 1314 ntohs(socket_get_port (data_addr))); 1315 verbose = overbose; 1316 1317 if (result == ERROR) { 1318 struct sockaddr_in *sin = (struct sockaddr_in *)data_addr; 1319 1320 unsigned int a = ntohl(sin->sin_addr.s_addr); 1321 unsigned int p = ntohs(sin->sin_port); 1322 1323 if (data_addr->sa_family != AF_INET) { 1324 warnx ("remote server doesn't support EPRT"); 1325 goto bad; 1326 } 1327 1328 result = command("PORT %d,%d,%d,%d,%d,%d", 1329 (a >> 24) & 0xff, 1330 (a >> 16) & 0xff, 1331 (a >> 8) & 0xff, 1332 a & 0xff, 1333 (p >> 8) & 0xff, 1334 p & 0xff); 1335 if (result == ERROR && sendport == -1) { 1336 sendport = 0; 1337 tmpno = 1; 1338 goto noport; 1339 } 1340 return (result != COMPLETE); 1341 } 1342 return result != COMPLETE; 1343 } 1344 if (tmpno) 1345 sendport = 1; 1346 1347 1348#ifdef IPTOS_THROUGHPUT 1349 socket_set_tos (data, IPTOS_THROUGHPUT); 1350#endif 1351 return (0); 1352bad: 1353 close (data); 1354 data = -1; 1355 if (tmpno) 1356 sendport = 1; 1357 return (1); 1358} 1359 1360/* 1361 * Need to start a listen on the data channel before we send the command, 1362 * otherwise the server's connect may fail. 1363 */ 1364int 1365initconn (void) 1366{ 1367 if (passivemode) 1368 return passive_mode (); 1369 else 1370 return active_mode (); 1371} 1372 1373FILE * 1374dataconn (const char *lmode) 1375{ 1376 struct sockaddr_storage from_ss; 1377 struct sockaddr *from = (struct sockaddr *)&from_ss; 1378 socklen_t fromlen = sizeof(from_ss); 1379 int s; 1380 1381 if (passivemode) 1382 return (fdopen (data, lmode)); 1383 1384 s = accept (data, from, &fromlen); 1385 if (s < 0) { 1386 warn ("accept"); 1387 close (data), data = -1; 1388 return (NULL); 1389 } 1390 close (data); 1391 data = s; 1392#ifdef IPTOS_THROUGHPUT 1393 socket_set_tos (s, IPTOS_THROUGHPUT); 1394#endif 1395 return (fdopen (data, lmode)); 1396} 1397 1398void 1399ptransfer (char *direction, long int bytes, 1400 struct timeval * t0, struct timeval * t1) 1401{ 1402 struct timeval td; 1403 float s; 1404 float bs; 1405 int prec; 1406 char *unit; 1407 1408 if (verbose) { 1409 td.tv_sec = t1->tv_sec - t0->tv_sec; 1410 td.tv_usec = t1->tv_usec - t0->tv_usec; 1411 if (td.tv_usec < 0) { 1412 td.tv_sec--; 1413 td.tv_usec += 1000000; 1414 } 1415 s = td.tv_sec + (td.tv_usec / 1000000.); 1416 bs = bytes / (s ? s : 1); 1417 if (bs >= 1048576) { 1418 bs /= 1048576; 1419 unit = "M"; 1420 prec = 2; 1421 } else if (bs >= 1024) { 1422 bs /= 1024; 1423 unit = "k"; 1424 prec = 1; 1425 } else { 1426 unit = ""; 1427 prec = 0; 1428 } 1429 1430 printf ("%ld bytes %s in %.3g seconds (%.*f %sbyte/s)\n", 1431 bytes, direction, s, prec, bs, unit); 1432 } 1433} 1434 1435void 1436psabort (int sig) 1437{ 1438 1439 abrtflag++; 1440} 1441 1442void 1443pswitch (int flag) 1444{ 1445 sighand oldintr; 1446 static struct comvars { 1447 int connect; 1448 char name[MaxHostNameLen]; 1449 struct sockaddr_storage mctl; 1450 struct sockaddr_storage hctl; 1451 FILE *in; 1452 FILE *out; 1453 int tpe; 1454 int curtpe; 1455 int cpnd; 1456 int sunqe; 1457 int runqe; 1458 int mcse; 1459 int ntflg; 1460 char nti[17]; 1461 char nto[17]; 1462 int mapflg; 1463 char mi[MaxPathLen]; 1464 char mo[MaxPathLen]; 1465 } proxstruct, tmpstruct; 1466 struct comvars *ip, *op; 1467 1468 abrtflag = 0; 1469 oldintr = signal (SIGINT, psabort); 1470 if (flag) { 1471 if (proxy) 1472 return; 1473 ip = &tmpstruct; 1474 op = &proxstruct; 1475 proxy++; 1476 } else { 1477 if (!proxy) 1478 return; 1479 ip = &proxstruct; 1480 op = &tmpstruct; 1481 proxy = 0; 1482 } 1483 ip->connect = connected; 1484 connected = op->connect; 1485 if (hostname) { 1486 strlcpy (ip->name, hostname, sizeof (ip->name)); 1487 } else 1488 ip->name[0] = 0; 1489 hostname = op->name; 1490 ip->hctl = hisctladdr_ss; 1491 hisctladdr_ss = op->hctl; 1492 ip->mctl = myctladdr_ss; 1493 myctladdr_ss = op->mctl; 1494 ip->in = cin; 1495 cin = op->in; 1496 ip->out = cout; 1497 cout = op->out; 1498 ip->tpe = type; 1499 type = op->tpe; 1500 ip->curtpe = curtype; 1501 curtype = op->curtpe; 1502 ip->cpnd = cpend; 1503 cpend = op->cpnd; 1504 ip->sunqe = sunique; 1505 sunique = op->sunqe; 1506 ip->runqe = runique; 1507 runique = op->runqe; 1508 ip->mcse = mcase; 1509 mcase = op->mcse; 1510 ip->ntflg = ntflag; 1511 ntflag = op->ntflg; 1512 strlcpy (ip->nti, ntin, sizeof (ip->nti)); 1513 strlcpy (ntin, op->nti, 17); 1514 strlcpy (ip->nto, ntout, sizeof (ip->nto)); 1515 strlcpy (ntout, op->nto, 17); 1516 ip->mapflg = mapflag; 1517 mapflag = op->mapflg; 1518 strlcpy (ip->mi, mapin, MaxPathLen); 1519 strlcpy (mapin, op->mi, MaxPathLen); 1520 strlcpy (ip->mo, mapout, MaxPathLen); 1521 strlcpy (mapout, op->mo, MaxPathLen); 1522 signal(SIGINT, oldintr); 1523 if (abrtflag) { 1524 abrtflag = 0; 1525 (*oldintr) (SIGINT); 1526 } 1527} 1528 1529void 1530abortpt (int sig) 1531{ 1532 1533 printf ("\n"); 1534 fflush (stdout); 1535 ptabflg++; 1536 mflag = 0; 1537 abrtflag = 0; 1538 longjmp (ptabort, 1); 1539} 1540 1541void 1542proxtrans (char *cmd, char *local, char *remote) 1543{ 1544 sighand oldintr; 1545 int secndflag = 0, prox_type, nfnd; 1546 char *cmd2; 1547 fd_set mask; 1548 1549 if (strcmp (cmd, "RETR")) 1550 cmd2 = "RETR"; 1551 else 1552 cmd2 = runique ? "STOU" : "STOR"; 1553 if ((prox_type = type) == 0) { 1554 if (unix_server && unix_proxy) 1555 prox_type = TYPE_I; 1556 else 1557 prox_type = TYPE_A; 1558 } 1559 if (curtype != prox_type) 1560 changetype (prox_type, 1); 1561 if (command ("PASV") != COMPLETE) { 1562 printf ("proxy server does not support third party transfers.\n"); 1563 return; 1564 } 1565 pswitch (0); 1566 if (!connected) { 1567 printf ("No primary connection\n"); 1568 pswitch (1); 1569 code = -1; 1570 return; 1571 } 1572 if (curtype != prox_type) 1573 changetype (prox_type, 1); 1574 if (command ("PORT %s", pasv) != COMPLETE) { 1575 pswitch (1); 1576 return; 1577 } 1578 if (setjmp (ptabort)) 1579 goto abort; 1580 oldintr = signal (SIGINT, abortpt); 1581 if (command ("%s %s", cmd, remote) != PRELIM) { 1582 signal (SIGINT, oldintr); 1583 pswitch (1); 1584 return; 1585 } 1586 sleep (2); 1587 pswitch (1); 1588 secndflag++; 1589 if (command ("%s %s", cmd2, local) != PRELIM) 1590 goto abort; 1591 ptflag++; 1592 getreply (0); 1593 pswitch (0); 1594 getreply (0); 1595 signal (SIGINT, oldintr); 1596 pswitch (1); 1597 ptflag = 0; 1598 printf ("local: %s remote: %s\n", local, remote); 1599 return; 1600abort: 1601 signal (SIGINT, SIG_IGN); 1602 ptflag = 0; 1603 if (strcmp (cmd, "RETR") && !proxy) 1604 pswitch (1); 1605 else if (!strcmp (cmd, "RETR") && proxy) 1606 pswitch (0); 1607 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ 1608 if (command ("%s %s", cmd2, local) != PRELIM) { 1609 pswitch (0); 1610 if (cpend) 1611 abort_remote ((FILE *) NULL); 1612 } 1613 pswitch (1); 1614 if (ptabflg) 1615 code = -1; 1616 signal (SIGINT, oldintr); 1617 return; 1618 } 1619 if (cpend) 1620 abort_remote ((FILE *) NULL); 1621 pswitch (!proxy); 1622 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */ 1623 if (command ("%s %s", cmd2, local) != PRELIM) { 1624 pswitch (0); 1625 if (cpend) 1626 abort_remote ((FILE *) NULL); 1627 pswitch (1); 1628 if (ptabflg) 1629 code = -1; 1630 signal (SIGINT, oldintr); 1631 return; 1632 } 1633 } 1634 if (cpend) 1635 abort_remote ((FILE *) NULL); 1636 pswitch (!proxy); 1637 if (cpend) { 1638 FD_ZERO (&mask); 1639 if (fileno(cin) >= FD_SETSIZE) 1640 errx (1, "fd too large"); 1641 FD_SET (fileno (cin), &mask); 1642 if ((nfnd = empty (&mask, 10)) <= 0) { 1643 if (nfnd < 0) { 1644 warn ("abort"); 1645 } 1646 if (ptabflg) 1647 code = -1; 1648 lostpeer (0); 1649 } 1650 getreply (0); 1651 getreply (0); 1652 } 1653 if (proxy) 1654 pswitch (0); 1655 pswitch (1); 1656 if (ptabflg) 1657 code = -1; 1658 signal (SIGINT, oldintr); 1659} 1660 1661void 1662reset (int argc, char **argv) 1663{ 1664 fd_set mask; 1665 int nfnd = 1; 1666 1667 FD_ZERO (&mask); 1668 while (nfnd > 0) { 1669 if (fileno (cin) >= FD_SETSIZE) 1670 errx (1, "fd too large"); 1671 FD_SET (fileno (cin), &mask); 1672 if ((nfnd = empty (&mask, 0)) < 0) { 1673 warn ("reset"); 1674 code = -1; 1675 lostpeer(0); 1676 } else if (nfnd) { 1677 getreply(0); 1678 } 1679 } 1680} 1681 1682char * 1683gunique (char *local) 1684{ 1685 static char new[MaxPathLen]; 1686 char *cp = strrchr (local, '/'); 1687 int d, count = 0; 1688 char ext = '1'; 1689 1690 if (cp) 1691 *cp = '\0'; 1692 d = access (cp ? local : ".", 2); 1693 if (cp) 1694 *cp = '/'; 1695 if (d < 0) { 1696 warn ("local: %s", local); 1697 return NULL; 1698 } 1699 strlcpy (new, local, sizeof(new)); 1700 cp = new + strlen(new); 1701 *cp++ = '.'; 1702 while (!d) { 1703 if (++count == 100) { 1704 printf ("runique: can't find unique file name.\n"); 1705 return NULL; 1706 } 1707 *cp++ = ext; 1708 *cp = '\0'; 1709 if (ext == '9') 1710 ext = '0'; 1711 else 1712 ext++; 1713 if ((d = access (new, 0)) < 0) 1714 break; 1715 if (ext != '0') 1716 cp--; 1717 else if (*(cp - 2) == '.') 1718 *(cp - 1) = '1'; 1719 else { 1720 *(cp - 2) = *(cp - 2) + 1; 1721 cp--; 1722 } 1723 } 1724 return (new); 1725} 1726 1727void 1728abort_remote (FILE * din) 1729{ 1730 char buf[BUFSIZ]; 1731 int nfnd; 1732 fd_set mask; 1733 1734 /* 1735 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark 1736 * after urgent byte rather than before as is protocol now 1737 */ 1738 snprintf (buf, sizeof (buf), "%c%c%c", IAC, IP, IAC); 1739 if (send (fileno (cout), buf, 3, MSG_OOB) != 3) 1740 warn ("abort"); 1741 fprintf (cout, "%cABOR\r\n", DM); 1742 fflush (cout); 1743 FD_ZERO (&mask); 1744 if (fileno (cin) >= FD_SETSIZE) 1745 errx (1, "fd too large"); 1746 FD_SET (fileno (cin), &mask); 1747 if (din) { 1748 if (fileno (din) >= FD_SETSIZE) 1749 errx (1, "fd too large"); 1750 FD_SET (fileno (din), &mask); 1751 } 1752 if ((nfnd = empty (&mask, 10)) <= 0) { 1753 if (nfnd < 0) { 1754 warn ("abort"); 1755 } 1756 if (ptabflg) 1757 code = -1; 1758 lostpeer (0); 1759 } 1760 if (din && FD_ISSET (fileno (din), &mask)) { 1761 while (read (fileno (din), buf, BUFSIZ) > 0) 1762 /* LOOP */ ; 1763 } 1764 if (getreply (0) == ERROR && code == 552) { 1765 /* 552 needed for nic style abort */ 1766 getreply (0); 1767 } 1768 getreply (0); 1769} 1770