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