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