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