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