1 /* $OpenBSD: ftp.c,v 1.86 2014/05/20 01:25:23 guenther Exp $ */ 2 /* $NetBSD: ftp.c,v 1.27 1997/08/18 10:20:23 lukem Exp $ */ 3 4 /* 5 * Copyright (C) 1997 and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1985, 1989, 1993, 1994 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 */ 61 62 #include <sys/types.h> 63 #include <sys/stat.h> 64 #include <sys/socket.h> 65 66 #include <netinet/in.h> 67 #include <netinet/in_systm.h> 68 #include <netinet/ip.h> 69 #include <arpa/inet.h> 70 #include <arpa/ftp.h> 71 #include <arpa/telnet.h> 72 73 #include <ctype.h> 74 #include <err.h> 75 #include <errno.h> 76 #include <netdb.h> 77 #include <poll.h> 78 #include <stdarg.h> 79 #include <stdio.h> 80 #include <stdlib.h> 81 #include <string.h> 82 #include <unistd.h> 83 #include <utime.h> 84 85 #include "ftp_var.h" 86 87 union sockunion { 88 struct sockinet { 89 u_char si_len; 90 u_char si_family; 91 u_short si_port; 92 } su_si; 93 struct sockaddr_in su_sin; 94 struct sockaddr_in6 su_sin6; 95 }; 96 #define su_len su_si.si_len 97 #define su_family su_si.si_family 98 #define su_port su_si.si_port 99 100 union sockunion myctladdr, hisctladdr, data_addr; 101 102 int data = -1; 103 int abrtflag = 0; 104 jmp_buf ptabort; 105 int ptabflg; 106 int ptflag = 0; 107 off_t restart_point = 0; 108 109 110 FILE *cin, *cout; 111 112 char * 113 hookup(char *host, char *port) 114 { 115 int s, tos, error; 116 static char hostnamebuf[MAXHOSTNAMELEN]; 117 struct addrinfo hints, *res, *res0, *ares; 118 char hbuf[NI_MAXHOST]; 119 char *cause = "unknown"; 120 socklen_t namelen; 121 122 epsv4bad = 0; 123 124 memset((char *)&hisctladdr, 0, sizeof (hisctladdr)); 125 memset(&hints, 0, sizeof(hints)); 126 hints.ai_flags = AI_CANONNAME; 127 hints.ai_family = family; 128 hints.ai_socktype = SOCK_STREAM; 129 hints.ai_protocol = 0; 130 error = getaddrinfo(host, port, &hints, &res0); 131 if (error == EAI_SERVICE) { 132 /* 133 * If the services file is corrupt/missing, fall back 134 * on our hard-coded defines. 135 */ 136 char pbuf[NI_MAXSERV]; 137 138 pbuf[0] = '\0'; 139 if (strcmp(port, "ftp") == 0) 140 snprintf(pbuf, sizeof(pbuf), "%d", FTP_PORT); 141 else if (strcmp(port, "ftpgate") == 0) 142 snprintf(pbuf, sizeof(pbuf), "%d", GATE_PORT); 143 else if (strcmp(port, "http") == 0) 144 snprintf(pbuf, sizeof(pbuf), "%d", HTTP_PORT); 145 #ifndef SMALL 146 else if (strcmp(port, "https") == 0) 147 snprintf(pbuf, sizeof(pbuf), "%d", HTTPS_PORT); 148 #endif /* !SMALL */ 149 if (pbuf[0]) 150 error = getaddrinfo(host, pbuf, &hints, &res0); 151 } 152 if (error) { 153 if (error == EAI_SERVICE) 154 warnx("%s: bad port number `%s'", host, port); 155 else 156 warnx("%s: %s", host, gai_strerror(error)); 157 code = -1; 158 return (0); 159 } 160 161 if (res0->ai_canonname) 162 strlcpy(hostnamebuf, res0->ai_canonname, sizeof(hostnamebuf)); 163 else 164 strlcpy(hostnamebuf, host, sizeof(hostnamebuf)); 165 hostname = hostnamebuf; 166 167 #ifndef SMALL 168 if (srcaddr) { 169 struct addrinfo ahints; 170 171 memset(&ahints, 0, sizeof(ahints)); 172 ahints.ai_family = family; 173 ahints.ai_socktype = SOCK_STREAM; 174 ahints.ai_flags |= AI_NUMERICHOST; 175 ahints.ai_protocol = 0; 176 177 error = getaddrinfo(srcaddr, NULL, &ahints, &ares); 178 if (error) { 179 warnx("%s: %s", srcaddr, gai_strerror(error)); 180 code = -1; 181 return (0); 182 } 183 } 184 #endif /* !SMALL */ 185 186 s = -1; 187 for (res = res0; res; res = res->ai_next) { 188 #if 0 /*old behavior*/ 189 if (res != res0) /* not on the first address */ 190 #else 191 if (res0->ai_next) /* if we have multiple possibilities */ 192 #endif 193 { 194 if (getnameinfo(res->ai_addr, res->ai_addrlen, 195 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 196 strlcpy(hbuf, "unknown", sizeof(hbuf)); 197 if (verbose) 198 fprintf(ttyout, "Trying %s...\n", hbuf); 199 } 200 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 201 if (s < 0) { 202 cause = "socket"; 203 continue; 204 } 205 #ifndef SMALL 206 if (srcaddr) { 207 if (ares->ai_family != res->ai_family) { 208 close(s); 209 s = -1; 210 errno = EINVAL; 211 cause = "bind"; 212 continue; 213 } 214 if (bind(s, ares->ai_addr, ares->ai_addrlen) < 0) { 215 cause = "bind"; 216 error = errno; 217 close(s); 218 errno = error; 219 s = -1; 220 continue; 221 } 222 } 223 #endif /* !SMALL */ 224 while ((error = connect(s, res->ai_addr, res->ai_addrlen)) < 0 225 && errno == EINTR) { 226 ; 227 } 228 if (error) { 229 /* this "if" clause is to prevent print warning twice */ 230 if (verbose && res->ai_next) { 231 if (getnameinfo(res->ai_addr, res->ai_addrlen, 232 hbuf, sizeof(hbuf), NULL, 0, 233 NI_NUMERICHOST) != 0) 234 strlcpy(hbuf, "(unknown)", 235 sizeof(hbuf)); 236 warn("connect to address %s", hbuf); 237 } 238 cause = "connect"; 239 error = errno; 240 close(s); 241 errno = error; 242 s = -1; 243 continue; 244 } 245 246 /* finally we got one */ 247 break; 248 } 249 if (s < 0) { 250 warn("%s", cause); 251 code = -1; 252 freeaddrinfo(res0); 253 return 0; 254 } 255 memcpy(&hisctladdr, res->ai_addr, res->ai_addrlen); 256 namelen = res->ai_addrlen; 257 freeaddrinfo(res0); 258 res0 = res = NULL; 259 #ifndef SMALL 260 if (srcaddr) { 261 freeaddrinfo(ares); 262 ares = NULL; 263 } 264 #endif /* !SMALL */ 265 if (getsockname(s, (struct sockaddr *)&myctladdr, &namelen) < 0) { 266 warn("getsockname"); 267 code = -1; 268 goto bad; 269 } 270 #if defined(IPPROTO_IP) && defined(IP_TOS) 271 if (hisctladdr.su_family == AF_INET) { 272 tos = IPTOS_LOWDELAY; 273 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) 274 warn("setsockopt TOS (ignored)"); 275 } 276 #endif 277 cin = fdopen(s, "r"); 278 cout = fdopen(s, "w"); 279 if (cin == NULL || cout == NULL) { 280 warnx("fdopen failed."); 281 if (cin) 282 (void)fclose(cin); 283 if (cout) 284 (void)fclose(cout); 285 code = -1; 286 goto bad; 287 } 288 if (verbose) 289 fprintf(ttyout, "Connected to %s.\n", hostname); 290 if (getreply(0) > 2) { /* read startup message from server */ 291 if (cin) 292 (void)fclose(cin); 293 if (cout) 294 (void)fclose(cout); 295 code = -1; 296 goto bad; 297 } 298 #ifdef SO_OOBINLINE 299 { 300 int ret, on = 1; 301 302 ret = setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)); 303 #ifndef SMALL 304 if (ret < 0 && debug) 305 warn("setsockopt"); 306 #endif /* !SMALL */ 307 } 308 #endif /* SO_OOBINLINE */ 309 310 return (hostname); 311 bad: 312 (void)close(s); 313 return ((char *)0); 314 } 315 316 /* ARGSUSED */ 317 void 318 cmdabort(int signo) 319 { 320 321 alarmtimer(0); 322 putc('\n', ttyout); 323 (void)fflush(ttyout); 324 abrtflag++; 325 if (ptflag) 326 longjmp(ptabort, 1); 327 } 328 329 /*VARARGS*/ 330 int 331 command(const char *fmt, ...) 332 { 333 va_list ap; 334 int r; 335 sig_t oldintr; 336 337 abrtflag = 0; 338 #ifndef SMALL 339 if (debug) { 340 fputs("---> ", ttyout); 341 va_start(ap, fmt); 342 if (strncmp("PASS ", fmt, 5) == 0) 343 fputs("PASS XXXX", ttyout); 344 else if (strncmp("ACCT ", fmt, 5) == 0) 345 fputs("ACCT XXXX", ttyout); 346 else 347 vfprintf(ttyout, fmt, ap); 348 va_end(ap); 349 putc('\n', ttyout); 350 (void)fflush(ttyout); 351 } 352 #endif /* !SMALL */ 353 if (cout == NULL) { 354 warnx("No control connection for command."); 355 code = -1; 356 return (0); 357 } 358 oldintr = signal(SIGINT, cmdabort); 359 va_start(ap, fmt); 360 vfprintf(cout, fmt, ap); 361 va_end(ap); 362 fputs("\r\n", cout); 363 (void)fflush(cout); 364 cpend = 1; 365 r = getreply(!strcmp(fmt, "QUIT")); 366 if (abrtflag && oldintr != SIG_IGN) 367 (*oldintr)(SIGINT); 368 (void)signal(SIGINT, oldintr); 369 return (r); 370 } 371 372 int keep_alive_timeout = 60; /* 0 -> no timeout */ 373 374 static int full_noops_sent = 0; 375 static time_t last_timestamp = 0; /* 0 -> no measurement yet */ 376 static char noop[] = "NOOP\r\n"; 377 #define NOOP_LENGTH (sizeof noop - 1) 378 static int current_nop_pos = 0; /* 0 -> no noop started */ 379 380 /* to achieve keep alive, we send noop one byte at a time */ 381 static void 382 send_noop_char(void) 383 { 384 #ifndef SMALL 385 if (debug) 386 fprintf(ttyout, "---> %c\n", noop[current_nop_pos]); 387 #endif /* !SMALL */ 388 fputc(noop[current_nop_pos++], cout); 389 (void)fflush(cout); 390 if (current_nop_pos >= NOOP_LENGTH) { 391 full_noops_sent++; 392 current_nop_pos = 0; 393 } 394 } 395 396 static void 397 may_reset_noop_timeout(void) 398 { 399 if (keep_alive_timeout != 0) 400 last_timestamp = time(NULL); 401 } 402 403 static void 404 may_receive_noop_ack(void) 405 { 406 int i; 407 408 if (cout == NULL) { 409 /* Lost connection; so just pretend we're fine. */ 410 current_nop_pos = full_noops_sent = 0; 411 return; 412 } 413 414 /* finish sending last incomplete noop */ 415 if (current_nop_pos != 0) { 416 fputs(&(noop[current_nop_pos]), cout); 417 #ifndef SMALL 418 if (debug) 419 fprintf(ttyout, "---> %s\n", &(noop[current_nop_pos])); 420 #endif /* !SMALL */ 421 (void)fflush(cout); 422 current_nop_pos = 0; 423 full_noops_sent++; 424 } 425 /* and get the replies */ 426 for (i = 0; i < full_noops_sent; i++) 427 (void)getreply(0); 428 429 full_noops_sent = 0; 430 } 431 432 static void 433 may_send_noop_char(void) 434 { 435 if (keep_alive_timeout != 0) { 436 if (last_timestamp != 0) { 437 time_t t = time(NULL); 438 439 if (t - last_timestamp >= keep_alive_timeout) { 440 last_timestamp = t; 441 send_noop_char(); 442 } 443 } else { 444 last_timestamp = time(NULL); 445 } 446 } 447 } 448 449 char reply_string[BUFSIZ]; /* first line of previous reply */ 450 451 int 452 getreply(int expecteof) 453 { 454 char current_line[BUFSIZ]; /* last line of previous reply */ 455 int c, n, lineno; 456 int dig; 457 int originalcode = 0, continuation = 0; 458 sig_t oldintr; 459 int pflag = 0; 460 char *cp, *pt = pasv; 461 462 memset(current_line, 0, sizeof(current_line)); 463 oldintr = signal(SIGINT, cmdabort); 464 for (lineno = 0 ;; lineno++) { 465 dig = n = code = 0; 466 cp = current_line; 467 while ((c = fgetc(cin)) != '\n') { 468 if (c == IAC) { /* handle telnet commands */ 469 switch (c = fgetc(cin)) { 470 case WILL: 471 case WONT: 472 c = fgetc(cin); 473 fprintf(cout, "%c%c%c", IAC, DONT, c); 474 (void)fflush(cout); 475 break; 476 case DO: 477 case DONT: 478 c = fgetc(cin); 479 fprintf(cout, "%c%c%c", IAC, WONT, c); 480 (void)fflush(cout); 481 break; 482 default: 483 break; 484 } 485 continue; 486 } 487 dig++; 488 if (c == EOF) { 489 if (expecteof) { 490 (void)signal(SIGINT, oldintr); 491 code = 221; 492 return (0); 493 } 494 lostpeer(); 495 if (verbose) { 496 fputs( 497 "421 Service not available, remote server has closed connection.\n", ttyout); 498 (void)fflush(ttyout); 499 } 500 code = 421; 501 return (4); 502 } 503 if (c != '\r' && (verbose > 0 || 504 ((verbose > -1 && n == '5' && dig > 4) && 505 (((!n && c < '5') || (n && n < '5')) 506 || !retry_connect)))) { 507 if (proxflag && 508 (dig == 1 || (dig == 5 && verbose == 0))) 509 fprintf(ttyout, "%s:", hostname); 510 (void)putc(c, ttyout); 511 } 512 if (dig < 4 && isdigit(c)) 513 code = code * 10 + (c - '0'); 514 if (!pflag && (code == 227 || code == 228)) 515 pflag = 1; 516 else if (!pflag && code == 229) 517 pflag = 100; 518 if (dig > 4 && pflag == 1 && isdigit(c)) 519 pflag = 2; 520 if (pflag == 2) { 521 if (c != '\r' && c != ')') { 522 if (pt < &pasv[sizeof(pasv) - 1]) 523 *pt++ = c; 524 } else { 525 *pt = '\0'; 526 pflag = 3; 527 } 528 } 529 if (pflag == 100 && c == '(') 530 pflag = 2; 531 if (dig == 4 && c == '-') { 532 if (continuation) 533 code = 0; 534 continuation++; 535 } 536 if (n == 0) 537 n = c; 538 if (cp < ¤t_line[sizeof(current_line) - 1]) 539 *cp++ = c; 540 } 541 if (verbose > 0 || ((verbose > -1 && n == '5') && 542 (n < '5' || !retry_connect))) { 543 (void)putc(c, ttyout); 544 (void)fflush (ttyout); 545 } 546 if (lineno == 0) { 547 size_t len = cp - current_line; 548 549 if (len > sizeof(reply_string)) 550 len = sizeof(reply_string); 551 552 (void)strlcpy(reply_string, current_line, len); 553 } 554 if (continuation && code != originalcode) { 555 if (originalcode == 0) 556 originalcode = code; 557 continue; 558 } 559 *cp = '\0'; 560 if (n != '1') 561 cpend = 0; 562 (void)signal(SIGINT, oldintr); 563 if (code == 421 || originalcode == 421) 564 lostpeer(); 565 if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN) 566 (*oldintr)(SIGINT); 567 return (n - '0'); 568 } 569 } 570 571 #ifndef SMALL 572 jmp_buf sendabort; 573 574 /* ARGSUSED */ 575 void 576 abortsend(int signo) 577 { 578 579 alarmtimer(0); 580 mflag = 0; 581 abrtflag = 0; 582 fputs("\nsend aborted\nwaiting for remote to finish abort.\n", ttyout); 583 (void)fflush(ttyout); 584 longjmp(sendabort, 1); 585 } 586 587 void 588 sendrequest(const char *cmd, const char *local, const char *remote, 589 int printnames) 590 { 591 struct stat st; 592 int c, d; 593 FILE * volatile fin, * volatile dout; 594 int (* volatile closefunc)(FILE *); 595 volatile sig_t oldinti, oldintr, oldintp; 596 volatile off_t hashbytes; 597 char * volatile lmode; 598 char buf[BUFSIZ], *bufp; 599 int oprogress, serrno; 600 601 hashbytes = mark; 602 direction = "sent"; 603 dout = NULL; 604 bytes = 0; 605 filesize = -1; 606 oprogress = progress; 607 if (verbose && printnames) { 608 if (local && *local != '-') 609 fprintf(ttyout, "local: %s ", local); 610 if (remote) 611 fprintf(ttyout, "remote: %s\n", remote); 612 } 613 if (proxy) { 614 proxtrans(cmd, local, remote); 615 return; 616 } 617 if (curtype != type) 618 changetype(type, 0); 619 closefunc = NULL; 620 oldintr = NULL; 621 oldintp = NULL; 622 oldinti = NULL; 623 lmode = "w"; 624 if (setjmp(sendabort)) { 625 while (cpend) { 626 (void)getreply(0); 627 } 628 if (data >= 0) { 629 (void)close(data); 630 data = -1; 631 } 632 if (oldintr) 633 (void)signal(SIGINT, oldintr); 634 if (oldintp) 635 (void)signal(SIGPIPE, oldintp); 636 if (oldinti) 637 (void)signal(SIGINFO, oldinti); 638 progress = oprogress; 639 code = -1; 640 return; 641 } 642 oldintr = signal(SIGINT, abortsend); 643 oldinti = signal(SIGINFO, psummary); 644 if (strcmp(local, "-") == 0) { 645 fin = stdin; 646 if (progress == 1) 647 progress = 0; 648 } else if (*local == '|') { 649 oldintp = signal(SIGPIPE, SIG_IGN); 650 fin = popen(local + 1, "r"); 651 if (fin == NULL) { 652 warn("%s", local + 1); 653 (void)signal(SIGINT, oldintr); 654 (void)signal(SIGPIPE, oldintp); 655 (void)signal(SIGINFO, oldinti); 656 code = -1; 657 return; 658 } 659 if (progress == 1) 660 progress = 0; 661 closefunc = pclose; 662 } else { 663 fin = fopen(local, "r"); 664 if (fin == NULL) { 665 warn("local: %s", local); 666 (void)signal(SIGINT, oldintr); 667 (void)signal(SIGINFO, oldinti); 668 code = -1; 669 return; 670 } 671 closefunc = fclose; 672 if (fstat(fileno(fin), &st) < 0 || 673 (st.st_mode & S_IFMT) != S_IFREG) { 674 fprintf(ttyout, "%s: not a plain file.\n", local); 675 (void)signal(SIGINT, oldintr); 676 (void)signal(SIGINFO, oldinti); 677 fclose(fin); 678 code = -1; 679 return; 680 } 681 filesize = st.st_size; 682 } 683 if (initconn()) { 684 (void)signal(SIGINT, oldintr); 685 (void)signal(SIGINFO, oldinti); 686 if (oldintp) 687 (void)signal(SIGPIPE, oldintp); 688 code = -1; 689 progress = oprogress; 690 if (closefunc != NULL) 691 (*closefunc)(fin); 692 return; 693 } 694 if (setjmp(sendabort)) 695 goto abort; 696 697 if (restart_point && 698 (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) { 699 int rc = -1; 700 701 switch (curtype) { 702 case TYPE_A: 703 rc = fseeko(fin, restart_point, SEEK_SET); 704 break; 705 case TYPE_I: 706 case TYPE_L: 707 if (lseek(fileno(fin), restart_point, SEEK_SET) != -1) 708 rc = 0; 709 break; 710 } 711 if (rc == -1) { 712 warn("local: %s", local); 713 progress = oprogress; 714 if (closefunc != NULL) 715 (*closefunc)(fin); 716 return; 717 } 718 if (command("REST %lld", (long long) restart_point) 719 != CONTINUE) { 720 progress = oprogress; 721 if (closefunc != NULL) 722 (*closefunc)(fin); 723 return; 724 } 725 lmode = "r+w"; 726 } 727 if (remote) { 728 if (command("%s %s", cmd, remote) != PRELIM) { 729 (void)signal(SIGINT, oldintr); 730 (void)signal(SIGINFO, oldinti); 731 progress = oprogress; 732 if (oldintp) 733 (void)signal(SIGPIPE, oldintp); 734 if (closefunc != NULL) 735 (*closefunc)(fin); 736 return; 737 } 738 } else 739 if (command("%s", cmd) != PRELIM) { 740 (void)signal(SIGINT, oldintr); 741 (void)signal(SIGINFO, oldinti); 742 progress = oprogress; 743 if (oldintp) 744 (void)signal(SIGPIPE, oldintp); 745 if (closefunc != NULL) 746 (*closefunc)(fin); 747 return; 748 } 749 dout = dataconn(lmode); 750 if (dout == NULL) 751 goto abort; 752 progressmeter(-1, remote); 753 may_reset_noop_timeout(); 754 oldintp = signal(SIGPIPE, SIG_IGN); 755 switch (curtype) { 756 757 case TYPE_I: 758 case TYPE_L: 759 d = 0; 760 while ((c = read(fileno(fin), buf, sizeof(buf))) > 0) { 761 may_send_noop_char(); 762 bytes += c; 763 for (bufp = buf; c > 0; c -= d, bufp += d) 764 if ((d = write(fileno(dout), bufp, (size_t)c)) 765 <= 0) 766 break; 767 if (hash && (!progress || filesize < 0) ) { 768 while (bytes >= hashbytes) { 769 (void)putc('#', ttyout); 770 hashbytes += mark; 771 } 772 (void)fflush(ttyout); 773 } 774 } 775 if (c == -1 || d == -1) 776 serrno = errno; 777 if (hash && (!progress || filesize < 0) && bytes > 0) { 778 if (bytes < mark) 779 (void)putc('#', ttyout); 780 (void)putc('\n', ttyout); 781 (void)fflush(ttyout); 782 } 783 if (c < 0) 784 warnc(serrno, "local: %s", local); 785 if (d < 0) { 786 if (serrno != EPIPE) 787 warnc(serrno, "netout"); 788 bytes = -1; 789 } 790 break; 791 792 case TYPE_A: 793 while ((c = fgetc(fin)) != EOF) { 794 may_send_noop_char(); 795 if (c == '\n') { 796 while (hash && (!progress || filesize < 0) && 797 (bytes >= hashbytes)) { 798 (void)putc('#', ttyout); 799 (void)fflush(ttyout); 800 hashbytes += mark; 801 } 802 if (ferror(dout)) 803 break; 804 (void)putc('\r', dout); 805 bytes++; 806 } 807 (void)putc(c, dout); 808 bytes++; 809 #if 0 /* this violates RFC */ 810 if (c == '\r') { 811 (void)putc('\0', dout); 812 bytes++; 813 } 814 #endif 815 } 816 if (ferror(fin) || ferror(dout)) 817 serrno = errno; 818 if (hash && (!progress || filesize < 0)) { 819 if (bytes < hashbytes) 820 (void)putc('#', ttyout); 821 (void)putc('\n', ttyout); 822 (void)fflush(ttyout); 823 } 824 if (ferror(fin)) 825 warnc(serrno, "local: %s", local); 826 if (ferror(dout)) { 827 if (errno != EPIPE) 828 warnc(serrno, "netout"); 829 bytes = -1; 830 } 831 break; 832 } 833 progressmeter(1, NULL); 834 progress = oprogress; 835 if (closefunc != NULL) 836 (*closefunc)(fin); 837 (void)fclose(dout); 838 (void)getreply(0); 839 may_receive_noop_ack(); 840 (void)signal(SIGINT, oldintr); 841 (void)signal(SIGINFO, oldinti); 842 if (oldintp) 843 (void)signal(SIGPIPE, oldintp); 844 if (bytes > 0) 845 ptransfer(0); 846 return; 847 abort: 848 (void)signal(SIGINT, oldintr); 849 (void)signal(SIGINFO, oldinti); 850 progress = oprogress; 851 if (oldintp) 852 (void)signal(SIGPIPE, oldintp); 853 if (!cpend) { 854 code = -1; 855 return; 856 } 857 if (data >= 0) { 858 (void)close(data); 859 data = -1; 860 } 861 if (dout) 862 (void)fclose(dout); 863 (void)getreply(0); 864 code = -1; 865 if (closefunc != NULL && fin != NULL) 866 (*closefunc)(fin); 867 if (bytes > 0) 868 ptransfer(0); 869 } 870 #endif /* !SMALL */ 871 872 jmp_buf recvabort; 873 874 /* ARGSUSED */ 875 void 876 abortrecv(int signo) 877 { 878 879 alarmtimer(0); 880 mflag = 0; 881 abrtflag = 0; 882 fputs("\nreceive aborted\nwaiting for remote to finish abort.\n", ttyout); 883 (void)fflush(ttyout); 884 longjmp(recvabort, 1); 885 } 886 887 void 888 recvrequest(const char *cmd, const char * volatile local, const char *remote, 889 const char *lmode, int printnames, int ignorespecial) 890 { 891 FILE * volatile fout, * volatile din; 892 int (* volatile closefunc)(FILE *); 893 volatile sig_t oldinti, oldintr, oldintp; 894 int c, d, serrno; 895 volatile int is_retr, tcrflag, bare_lfs; 896 static size_t bufsize; 897 static char *buf; 898 volatile off_t hashbytes; 899 struct stat st; 900 time_t mtime; 901 int oprogress; 902 int opreserve; 903 904 fout = NULL; 905 din = NULL; 906 oldinti = NULL; 907 hashbytes = mark; 908 direction = "received"; 909 bytes = 0; 910 bare_lfs = 0; 911 filesize = -1; 912 oprogress = progress; 913 opreserve = preserve; 914 is_retr = strcmp(cmd, "RETR") == 0; 915 if (is_retr && verbose && printnames) { 916 if (local && (ignorespecial || *local != '-')) 917 fprintf(ttyout, "local: %s ", local); 918 if (remote) 919 fprintf(ttyout, "remote: %s\n", remote); 920 } 921 if (proxy && is_retr) { 922 proxtrans(cmd, local, remote); 923 return; 924 } 925 closefunc = NULL; 926 oldintr = NULL; 927 oldintp = NULL; 928 tcrflag = !crflag && is_retr; 929 if (setjmp(recvabort)) { 930 while (cpend) { 931 (void)getreply(0); 932 } 933 if (data >= 0) { 934 (void)close(data); 935 data = -1; 936 } 937 if (oldintr) 938 (void)signal(SIGINT, oldintr); 939 if (oldinti) 940 (void)signal(SIGINFO, oldinti); 941 progress = oprogress; 942 preserve = opreserve; 943 code = -1; 944 return; 945 } 946 oldintr = signal(SIGINT, abortrecv); 947 oldinti = signal(SIGINFO, psummary); 948 if (ignorespecial || (strcmp(local, "-") && *local != '|')) { 949 if (access(local, W_OK) < 0) { 950 char *dir; 951 952 if (errno != ENOENT && errno != EACCES) { 953 warn("local: %s", local); 954 (void)signal(SIGINT, oldintr); 955 (void)signal(SIGINFO, oldinti); 956 code = -1; 957 return; 958 } 959 dir = strrchr(local, '/'); 960 if (dir != NULL) 961 *dir = 0; 962 d = access(dir == local ? "/" : dir ? local : ".", W_OK); 963 if (dir != NULL) 964 *dir = '/'; 965 if (d < 0) { 966 warn("local: %s", local); 967 (void)signal(SIGINT, oldintr); 968 (void)signal(SIGINFO, oldinti); 969 code = -1; 970 return; 971 } 972 if (!runique && errno == EACCES && 973 chmod(local, (S_IRUSR|S_IWUSR)) < 0) { 974 warn("local: %s", local); 975 (void)signal(SIGINT, oldintr); 976 (void)signal(SIGINFO, oldinti); 977 code = -1; 978 return; 979 } 980 if (runique && errno == EACCES && 981 (local = gunique(local)) == NULL) { 982 (void)signal(SIGINT, oldintr); 983 (void)signal(SIGINFO, oldinti); 984 code = -1; 985 return; 986 } 987 } 988 else if (runique && (local = gunique(local)) == NULL) { 989 (void)signal(SIGINT, oldintr); 990 (void)signal(SIGINFO, oldinti); 991 code = -1; 992 return; 993 } 994 } 995 if (!is_retr) { 996 if (curtype != TYPE_A) 997 changetype(TYPE_A, 0); 998 } else { 999 if (curtype != type) 1000 changetype(type, 0); 1001 filesize = remotesize(remote, 0); 1002 } 1003 if (initconn()) { 1004 (void)signal(SIGINT, oldintr); 1005 (void)signal(SIGINFO, oldinti); 1006 code = -1; 1007 return; 1008 } 1009 if (setjmp(recvabort)) 1010 goto abort; 1011 if (is_retr && restart_point && 1012 command("REST %lld", (long long) restart_point) != CONTINUE) 1013 return; 1014 if (remote) { 1015 if (command("%s %s", cmd, remote) != PRELIM) { 1016 (void)signal(SIGINT, oldintr); 1017 (void)signal(SIGINFO, oldinti); 1018 return; 1019 } 1020 } else { 1021 if (command("%s", cmd) != PRELIM) { 1022 (void)signal(SIGINT, oldintr); 1023 (void)signal(SIGINFO, oldinti); 1024 return; 1025 } 1026 } 1027 din = dataconn("r"); 1028 if (din == NULL) 1029 goto abort; 1030 if (!ignorespecial && strcmp(local, "-") == 0) { 1031 fout = stdout; 1032 preserve = 0; 1033 } else if (!ignorespecial && *local == '|') { 1034 oldintp = signal(SIGPIPE, SIG_IGN); 1035 fout = popen(local + 1, "w"); 1036 if (fout == NULL) { 1037 warn("%s", local+1); 1038 goto abort; 1039 } 1040 if (progress == 1) 1041 progress = 0; 1042 preserve = 0; 1043 closefunc = pclose; 1044 } else { 1045 fout = fopen(local, lmode); 1046 if (fout == NULL) { 1047 warn("local: %s", local); 1048 goto abort; 1049 } 1050 closefunc = fclose; 1051 } 1052 if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0) 1053 st.st_blksize = BUFSIZ; 1054 if (st.st_blksize > bufsize) { 1055 (void)free(buf); 1056 buf = malloc((unsigned)st.st_blksize); 1057 if (buf == NULL) { 1058 warn("malloc"); 1059 bufsize = 0; 1060 goto abort; 1061 } 1062 bufsize = st.st_blksize; 1063 } 1064 if ((st.st_mode & S_IFMT) != S_IFREG) { 1065 if (progress == 1) 1066 progress = 0; 1067 preserve = 0; 1068 } 1069 progressmeter(-1, remote); 1070 may_reset_noop_timeout(); 1071 switch (curtype) { 1072 1073 case TYPE_I: 1074 case TYPE_L: 1075 if (restart_point && 1076 lseek(fileno(fout), restart_point, SEEK_SET) < 0) { 1077 warn("local: %s", local); 1078 progress = oprogress; 1079 preserve = opreserve; 1080 if (closefunc != NULL) 1081 (*closefunc)(fout); 1082 return; 1083 } 1084 errno = d = 0; 1085 while ((c = read(fileno(din), buf, bufsize)) > 0) { 1086 ssize_t wr; 1087 size_t rd = c; 1088 1089 may_send_noop_char(); 1090 d = 0; 1091 do { 1092 wr = write(fileno(fout), buf + d, rd); 1093 if (wr == -1) { 1094 d = -1; 1095 break; 1096 } 1097 d += wr; 1098 rd -= wr; 1099 } while (d < c); 1100 if (rd != 0) 1101 break; 1102 bytes += c; 1103 if (hash && (!progress || filesize < 0)) { 1104 while (bytes >= hashbytes) { 1105 (void)putc('#', ttyout); 1106 hashbytes += mark; 1107 } 1108 (void)fflush(ttyout); 1109 } 1110 } 1111 if (c == -1 || d < c) 1112 serrno = errno; 1113 if (hash && (!progress || filesize < 0) && bytes > 0) { 1114 if (bytes < mark) 1115 (void)putc('#', ttyout); 1116 (void)putc('\n', ttyout); 1117 (void)fflush(ttyout); 1118 } 1119 if (c < 0) { 1120 if (serrno != EPIPE) 1121 warnc(serrno, "netin"); 1122 bytes = -1; 1123 } 1124 if (d < c) { 1125 if (d < 0) 1126 warnc(serrno, "local: %s", local); 1127 else 1128 warnx("%s: short write", local); 1129 } 1130 break; 1131 1132 case TYPE_A: 1133 if (restart_point) { 1134 int i, n, ch; 1135 1136 if (fseek(fout, 0L, SEEK_SET) < 0) 1137 goto done; 1138 n = restart_point; 1139 for (i = 0; i++ < n;) { 1140 if ((ch = fgetc(fout)) == EOF) { 1141 if (!ferror(fout)) 1142 errno = 0; 1143 goto done; 1144 } 1145 if (ch == '\n') 1146 i++; 1147 } 1148 if (fseek(fout, 0L, SEEK_CUR) < 0) { 1149 done: 1150 if (errno) 1151 warn("local: %s", local); 1152 else 1153 warnx("local: %s", local); 1154 progress = oprogress; 1155 preserve = opreserve; 1156 if (closefunc != NULL) 1157 (*closefunc)(fout); 1158 return; 1159 } 1160 } 1161 while ((c = fgetc(din)) != EOF) { 1162 may_send_noop_char(); 1163 if (c == '\n') 1164 bare_lfs++; 1165 while (c == '\r') { 1166 while (hash && (!progress || filesize < 0) && 1167 (bytes >= hashbytes)) { 1168 (void)putc('#', ttyout); 1169 (void)fflush(ttyout); 1170 hashbytes += mark; 1171 } 1172 bytes++; 1173 if ((c = fgetc(din)) != '\n' || tcrflag) { 1174 if (ferror(fout)) 1175 goto break2; 1176 (void)putc('\r', fout); 1177 if (c == '\0') { 1178 bytes++; 1179 goto contin2; 1180 } 1181 if (c == EOF) 1182 goto contin2; 1183 } 1184 } 1185 (void)putc(c, fout); 1186 bytes++; 1187 contin2: ; 1188 } 1189 break2: 1190 if (ferror(din) || ferror(fout)) 1191 serrno = errno; 1192 if (bare_lfs) { 1193 fprintf(ttyout, 1194 "WARNING! %d bare linefeeds received in ASCII mode.\n", bare_lfs); 1195 fputs("File may not have transferred correctly.\n", 1196 ttyout); 1197 } 1198 if (hash && (!progress || filesize < 0)) { 1199 if (bytes < hashbytes) 1200 (void)putc('#', ttyout); 1201 (void)putc('\n', ttyout); 1202 (void)fflush(ttyout); 1203 } 1204 if (ferror(din)) { 1205 if (serrno != EPIPE) 1206 warnc(serrno, "netin"); 1207 bytes = -1; 1208 } 1209 if (ferror(fout)) 1210 warnc(serrno, "local: %s", local); 1211 break; 1212 } 1213 progressmeter(1, NULL); 1214 progress = oprogress; 1215 preserve = opreserve; 1216 if (closefunc != NULL) 1217 (*closefunc)(fout); 1218 (void)signal(SIGINT, oldintr); 1219 (void)signal(SIGINFO, oldinti); 1220 if (oldintp) 1221 (void)signal(SIGPIPE, oldintp); 1222 (void)fclose(din); 1223 (void)getreply(0); 1224 may_receive_noop_ack(); 1225 if (bytes >= 0 && is_retr) { 1226 if (bytes > 0) 1227 ptransfer(0); 1228 if (preserve && (closefunc == fclose)) { 1229 mtime = remotemodtime(remote, 0); 1230 if (mtime != -1) { 1231 struct utimbuf ut; 1232 1233 ut.actime = time(NULL); 1234 ut.modtime = mtime; 1235 if (utime(local, &ut) == -1) 1236 fprintf(ttyout, 1237 "Can't change modification time on %s to %s", 1238 local, asctime(localtime(&mtime))); 1239 } 1240 } 1241 } 1242 return; 1243 1244 abort: 1245 /* abort using RFC959 recommended IP,SYNC sequence */ 1246 progress = oprogress; 1247 preserve = opreserve; 1248 if (oldintp) 1249 (void)signal(SIGPIPE, oldintp); 1250 (void)signal(SIGINT, SIG_IGN); 1251 if (!cpend) { 1252 code = -1; 1253 (void)signal(SIGINT, oldintr); 1254 (void)signal(SIGINFO, oldinti); 1255 return; 1256 } 1257 1258 abort_remote(din); 1259 code = -1; 1260 if (data >= 0) { 1261 (void)close(data); 1262 data = -1; 1263 } 1264 if (closefunc != NULL && fout != NULL) 1265 (*closefunc)(fout); 1266 if (din) 1267 (void)fclose(din); 1268 if (bytes > 0) 1269 ptransfer(0); 1270 (void)signal(SIGINT, oldintr); 1271 (void)signal(SIGINFO, oldinti); 1272 } 1273 1274 /* 1275 * Need to start a listen on the data channel before we send the command, 1276 * otherwise the server's connect may fail. 1277 */ 1278 int 1279 initconn(void) 1280 { 1281 char *p, *a; 1282 int result = ERROR, tmpno = 0; 1283 int on = 1; 1284 int error; 1285 u_int addr[16], port[2]; 1286 u_int af, hal, pal; 1287 char *pasvcmd = NULL; 1288 socklen_t namelen; 1289 struct addrinfo *ares; 1290 1291 if (myctladdr.su_family == AF_INET6 1292 && (IN6_IS_ADDR_LINKLOCAL(&myctladdr.su_sin6.sin6_addr) 1293 || IN6_IS_ADDR_SITELOCAL(&myctladdr.su_sin6.sin6_addr))) { 1294 warnx("use of scoped address can be troublesome"); 1295 } 1296 #ifndef SMALL 1297 if (srcaddr) { 1298 struct addrinfo ahints; 1299 1300 memset(&ahints, 0, sizeof(ahints)); 1301 ahints.ai_family = family; 1302 ahints.ai_socktype = SOCK_STREAM; 1303 ahints.ai_flags |= AI_NUMERICHOST; 1304 ahints.ai_protocol = 0; 1305 1306 error = getaddrinfo(srcaddr, NULL, &ahints, &ares); 1307 if (error) { 1308 warnx("%s: %s", srcaddr, gai_strerror(error)); 1309 code = -1; 1310 return (0); 1311 } 1312 } 1313 #endif /* !SMALL */ 1314 reinit: 1315 if (passivemode) { 1316 data_addr = myctladdr; 1317 data = socket(data_addr.su_family, SOCK_STREAM, 0); 1318 if (data < 0) { 1319 warn("socket"); 1320 return (1); 1321 } 1322 #ifndef SMALL 1323 if (srcaddr) { 1324 if (bind(data, ares->ai_addr, ares->ai_addrlen) < 0) { 1325 warn("bind"); 1326 close(data); 1327 return (1); 1328 } 1329 } 1330 if ((options & SO_DEBUG) && 1331 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, 1332 sizeof(on)) < 0) 1333 warn("setsockopt (ignored)"); 1334 #endif /* !SMALL */ 1335 switch (data_addr.su_family) { 1336 case AF_INET: 1337 if (epsv4 && !epsv4bad) { 1338 int ov; 1339 /* shut this command up in case it fails */ 1340 ov = verbose; 1341 verbose = -1; 1342 result = command(pasvcmd = "EPSV"); 1343 /* 1344 * now back to whatever verbosity we had before 1345 * and we can try PASV 1346 */ 1347 verbose = ov; 1348 if (code / 10 == 22 && code != 229) { 1349 fputs( 1350 "wrong server: return code must be 229\n", 1351 ttyout); 1352 result = COMPLETE + 1; 1353 } 1354 if (result != COMPLETE) { 1355 epsv4bad = 1; 1356 #ifndef SMALL 1357 if (debug) { 1358 fputs( 1359 "disabling epsv4 for this connection\n", 1360 ttyout); 1361 } 1362 #endif /* !SMALL */ 1363 } 1364 } 1365 if (result != COMPLETE) 1366 result = command(pasvcmd = "PASV"); 1367 break; 1368 case AF_INET6: 1369 result = command(pasvcmd = "EPSV"); 1370 if (code / 10 == 22 && code != 229) { 1371 fputs( 1372 "wrong server: return code must be 229\n", 1373 ttyout); 1374 result = COMPLETE + 1; 1375 } 1376 if (result != COMPLETE) 1377 result = command(pasvcmd = "LPSV"); 1378 break; 1379 default: 1380 result = COMPLETE + 1; 1381 break; 1382 } 1383 if (result != COMPLETE) { 1384 if (activefallback) { 1385 (void)close(data); 1386 data = -1; 1387 passivemode = 0; 1388 activefallback = 0; 1389 goto reinit; 1390 } 1391 fputs("Passive mode refused.\n", ttyout); 1392 goto bad; 1393 } 1394 1395 #define pack2(var, off) \ 1396 (((var[(off) + 0] & 0xff) << 8) | ((var[(off) + 1] & 0xff) << 0)) 1397 #define pack4(var, off) \ 1398 (((var[(off) + 0] & 0xff) << 24) | ((var[(off) + 1] & 0xff) << 16) | \ 1399 ((var[(off) + 2] & 0xff) << 8) | ((var[(off) + 3] & 0xff) << 0)) 1400 1401 /* 1402 * What we've got at this point is a string of comma separated 1403 * one-byte unsigned integer values, separated by commas. 1404 */ 1405 if (!pasvcmd) 1406 goto bad; 1407 if (strcmp(pasvcmd, "PASV") == 0) { 1408 if (data_addr.su_family != AF_INET) { 1409 fputs( 1410 "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); 1411 goto bad; 1412 } 1413 if (code / 10 == 22 && code != 227) { 1414 fputs("wrong server: return code must be 227\n", 1415 ttyout); 1416 goto bad; 1417 } 1418 error = sscanf(pasv, "%u,%u,%u,%u,%u,%u", 1419 &addr[0], &addr[1], &addr[2], &addr[3], 1420 &port[0], &port[1]); 1421 if (error != 6) { 1422 fputs( 1423 "Passive mode address scan failure. Shouldn't happen!\n", ttyout); 1424 goto bad; 1425 } 1426 memset(&data_addr, 0, sizeof(data_addr)); 1427 data_addr.su_family = AF_INET; 1428 data_addr.su_len = sizeof(struct sockaddr_in); 1429 data_addr.su_sin.sin_addr.s_addr = 1430 htonl(pack4(addr, 0)); 1431 data_addr.su_port = htons(pack2(port, 0)); 1432 } else if (strcmp(pasvcmd, "LPSV") == 0) { 1433 if (code / 10 == 22 && code != 228) { 1434 fputs("wrong server: return code must be 228\n", 1435 ttyout); 1436 goto bad; 1437 } 1438 switch (data_addr.su_family) { 1439 case AF_INET: 1440 error = sscanf(pasv, 1441 "%u,%u,%u,%u,%u,%u,%u,%u,%u", 1442 &af, &hal, 1443 &addr[0], &addr[1], &addr[2], &addr[3], 1444 &pal, &port[0], &port[1]); 1445 if (error != 9) { 1446 fputs( 1447 "Passive mode address scan failure. Shouldn't happen!\n", ttyout); 1448 goto bad; 1449 } 1450 if (af != 4 || hal != 4 || pal != 2) { 1451 fputs( 1452 "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); 1453 error = 1; 1454 goto bad; 1455 } 1456 1457 memset(&data_addr, 0, sizeof(data_addr)); 1458 data_addr.su_family = AF_INET; 1459 data_addr.su_len = sizeof(struct sockaddr_in); 1460 data_addr.su_sin.sin_addr.s_addr = 1461 htonl(pack4(addr, 0)); 1462 data_addr.su_port = htons(pack2(port, 0)); 1463 break; 1464 case AF_INET6: 1465 error = sscanf(pasv, 1466 "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", 1467 &af, &hal, 1468 &addr[0], &addr[1], &addr[2], &addr[3], 1469 &addr[4], &addr[5], &addr[6], &addr[7], 1470 &addr[8], &addr[9], &addr[10], 1471 &addr[11], &addr[12], &addr[13], 1472 &addr[14], &addr[15], 1473 &pal, &port[0], &port[1]); 1474 if (error != 21) { 1475 fputs( 1476 "Passive mode address scan failure. Shouldn't happen!\n", ttyout); 1477 goto bad; 1478 } 1479 if (af != 6 || hal != 16 || pal != 2) { 1480 fputs( 1481 "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); 1482 goto bad; 1483 } 1484 1485 memset(&data_addr, 0, sizeof(data_addr)); 1486 data_addr.su_family = AF_INET6; 1487 data_addr.su_len = sizeof(struct sockaddr_in6); 1488 { 1489 u_int32_t *p32; 1490 p32 = (u_int32_t *)&data_addr.su_sin6.sin6_addr; 1491 p32[0] = htonl(pack4(addr, 0)); 1492 p32[1] = htonl(pack4(addr, 4)); 1493 p32[2] = htonl(pack4(addr, 8)); 1494 p32[3] = htonl(pack4(addr, 12)); 1495 } 1496 data_addr.su_port = htons(pack2(port, 0)); 1497 break; 1498 default: 1499 fputs("Bad family!\n", ttyout); 1500 goto bad; 1501 } 1502 } else if (strcmp(pasvcmd, "EPSV") == 0) { 1503 char delim[4]; 1504 1505 port[0] = 0; 1506 if (code / 10 == 22 && code != 229) { 1507 fputs("wrong server: return code must be 229\n", 1508 ttyout); 1509 goto bad; 1510 } 1511 if (sscanf(pasv, "%c%c%c%d%c", &delim[0], 1512 &delim[1], &delim[2], &port[1], 1513 &delim[3]) != 5) { 1514 fputs("parse error!\n", ttyout); 1515 goto bad; 1516 } 1517 if (delim[0] != delim[1] || delim[0] != delim[2] 1518 || delim[0] != delim[3]) { 1519 fputs("parse error!\n", ttyout); 1520 goto bad; 1521 } 1522 data_addr = hisctladdr; 1523 data_addr.su_port = htons(port[1]); 1524 } else 1525 goto bad; 1526 1527 while (connect(data, (struct sockaddr *)&data_addr, 1528 data_addr.su_len) < 0) { 1529 if (errno == EINTR) 1530 continue; 1531 if (activefallback) { 1532 (void)close(data); 1533 data = -1; 1534 passivemode = 0; 1535 activefallback = 0; 1536 goto reinit; 1537 } 1538 warn("connect"); 1539 goto bad; 1540 } 1541 #if defined(IPPROTO_IP) && defined(IP_TOS) 1542 if (data_addr.su_family == AF_INET) { 1543 on = IPTOS_THROUGHPUT; 1544 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, 1545 sizeof(int)) < 0) 1546 warn("setsockopt TOS (ignored)"); 1547 } 1548 #endif 1549 return (0); 1550 } 1551 1552 noport: 1553 data_addr = myctladdr; 1554 if (sendport) 1555 data_addr.su_port = 0; /* let system pick one */ 1556 if (data != -1) 1557 (void)close(data); 1558 data = socket(data_addr.su_family, SOCK_STREAM, 0); 1559 if (data < 0) { 1560 warn("socket"); 1561 if (tmpno) 1562 sendport = 1; 1563 return (1); 1564 } 1565 if (!sendport) 1566 if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, 1567 sizeof(on)) < 0) { 1568 warn("setsockopt (reuse address)"); 1569 goto bad; 1570 } 1571 switch (data_addr.su_family) { 1572 case AF_INET: 1573 on = IP_PORTRANGE_HIGH; 1574 if (setsockopt(data, IPPROTO_IP, IP_PORTRANGE, 1575 (char *)&on, sizeof(on)) < 0) 1576 warn("setsockopt IP_PORTRANGE (ignored)"); 1577 break; 1578 case AF_INET6: 1579 on = IPV6_PORTRANGE_HIGH; 1580 if (setsockopt(data, IPPROTO_IPV6, IPV6_PORTRANGE, 1581 (char *)&on, sizeof(on)) < 0) 1582 warn("setsockopt IPV6_PORTRANGE (ignored)"); 1583 break; 1584 } 1585 if (bind(data, (struct sockaddr *)&data_addr, data_addr.su_len) < 0) { 1586 warn("bind"); 1587 goto bad; 1588 } 1589 #ifndef SMALL 1590 if (options & SO_DEBUG && 1591 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, 1592 sizeof(on)) < 0) 1593 warn("setsockopt (ignored)"); 1594 #endif /* !SMALL */ 1595 namelen = sizeof(data_addr); 1596 if (getsockname(data, (struct sockaddr *)&data_addr, &namelen) < 0) { 1597 warn("getsockname"); 1598 goto bad; 1599 } 1600 if (listen(data, 1) < 0) 1601 warn("listen"); 1602 1603 #define UC(b) (((int)b)&0xff) 1604 1605 if (sendport) { 1606 char hname[NI_MAXHOST], pbuf[NI_MAXSERV]; 1607 int af_tmp; 1608 union sockunion tmp; 1609 1610 tmp = data_addr; 1611 switch (tmp.su_family) { 1612 case AF_INET: 1613 if (!epsv4 || epsv4bad) { 1614 result = COMPLETE +1; 1615 break; 1616 } 1617 /*FALLTHROUGH*/ 1618 case AF_INET6: 1619 if (tmp.su_family == AF_INET6) 1620 tmp.su_sin6.sin6_scope_id = 0; 1621 af_tmp = (tmp.su_family == AF_INET) ? 1 : 2; 1622 if (getnameinfo((struct sockaddr *)&tmp, 1623 tmp.su_len, hname, sizeof(hname), 1624 pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { 1625 result = ERROR; 1626 } else { 1627 result = command("EPRT |%d|%s|%s|", 1628 af_tmp, hname, pbuf); 1629 if (result != COMPLETE) { 1630 epsv4bad = 1; 1631 #ifndef SMALL 1632 if (debug) { 1633 fputs( 1634 "disabling epsv4 for this connection\n", 1635 ttyout); 1636 } 1637 #endif /* !SMALL */ 1638 } 1639 } 1640 break; 1641 default: 1642 result = COMPLETE + 1; 1643 break; 1644 } 1645 if (result == COMPLETE) 1646 goto skip_port; 1647 1648 switch (data_addr.su_family) { 1649 case AF_INET: 1650 a = (char *)&data_addr.su_sin.sin_addr; 1651 p = (char *)&data_addr.su_port; 1652 result = command("PORT %d,%d,%d,%d,%d,%d", 1653 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 1654 UC(p[0]), UC(p[1])); 1655 break; 1656 case AF_INET6: 1657 a = (char *)&data_addr.su_sin6.sin6_addr; 1658 p = (char *)&data_addr.su_port; 1659 result = command( 1660 "LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", 1661 6, 16, 1662 UC(a[0]),UC(a[1]),UC(a[2]),UC(a[3]), 1663 UC(a[4]),UC(a[5]),UC(a[6]),UC(a[7]), 1664 UC(a[8]),UC(a[9]),UC(a[10]),UC(a[11]), 1665 UC(a[12]),UC(a[13]),UC(a[14]),UC(a[15]), 1666 2, UC(p[0]), UC(p[1])); 1667 break; 1668 default: 1669 result = COMPLETE + 1; /* xxx */ 1670 } 1671 skip_port: 1672 1673 if (result == ERROR && sendport == -1) { 1674 sendport = 0; 1675 tmpno = 1; 1676 goto noport; 1677 } 1678 return (result != COMPLETE); 1679 } 1680 if (tmpno) 1681 sendport = 1; 1682 #if defined(IPPROTO_IP) && defined(IP_TOS) 1683 if (data_addr.su_family == AF_INET) { 1684 on = IPTOS_THROUGHPUT; 1685 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, 1686 sizeof(int)) < 0) 1687 warn("setsockopt TOS (ignored)"); 1688 } 1689 #endif 1690 return (0); 1691 bad: 1692 (void)close(data), data = -1; 1693 if (tmpno) 1694 sendport = 1; 1695 return (1); 1696 } 1697 1698 FILE * 1699 dataconn(const char *lmode) 1700 { 1701 union sockunion from; 1702 socklen_t fromlen = myctladdr.su_len; 1703 int s; 1704 1705 if (passivemode) 1706 return (fdopen(data, lmode)); 1707 1708 s = accept(data, (struct sockaddr *) &from, &fromlen); 1709 if (s < 0) { 1710 warn("accept"); 1711 (void)close(data), data = -1; 1712 return (NULL); 1713 } 1714 (void)close(data); 1715 data = s; 1716 #if defined(IPPROTO_IP) && defined(IP_TOS) 1717 if (from.su_family == AF_INET) { 1718 int tos = IPTOS_THROUGHPUT; 1719 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, 1720 sizeof(int)) < 0) { 1721 warn("setsockopt TOS (ignored)"); 1722 } 1723 } 1724 #endif 1725 return (fdopen(data, lmode)); 1726 } 1727 1728 /* ARGSUSED */ 1729 void 1730 psummary(int signo) 1731 { 1732 int save_errno = errno; 1733 1734 if (bytes > 0) 1735 ptransfer(1); 1736 errno = save_errno; 1737 } 1738 1739 /* ARGSUSED */ 1740 void 1741 psabort(int signo) 1742 { 1743 1744 alarmtimer(0); 1745 abrtflag++; 1746 } 1747 1748 void 1749 pswitch(int flag) 1750 { 1751 sig_t oldintr; 1752 static struct comvars { 1753 int connect; 1754 char name[MAXHOSTNAMELEN]; 1755 union sockunion mctl; 1756 union sockunion hctl; 1757 FILE *in; 1758 FILE *out; 1759 int tpe; 1760 int curtpe; 1761 int cpnd; 1762 int sunqe; 1763 int runqe; 1764 int mcse; 1765 int ntflg; 1766 char nti[17]; 1767 char nto[17]; 1768 int mapflg; 1769 char mi[MAXPATHLEN]; 1770 char mo[MAXPATHLEN]; 1771 } proxstruct, tmpstruct; 1772 struct comvars *ip, *op; 1773 1774 abrtflag = 0; 1775 oldintr = signal(SIGINT, psabort); 1776 if (flag) { 1777 if (proxy) 1778 return; 1779 ip = &tmpstruct; 1780 op = &proxstruct; 1781 proxy++; 1782 } else { 1783 if (!proxy) 1784 return; 1785 ip = &proxstruct; 1786 op = &tmpstruct; 1787 proxy = 0; 1788 } 1789 ip->connect = connected; 1790 connected = op->connect; 1791 if (hostname) { 1792 (void)strlcpy(ip->name, hostname, sizeof(ip->name)); 1793 } else 1794 ip->name[0] = '\0'; 1795 hostname = op->name; 1796 ip->hctl = hisctladdr; 1797 hisctladdr = op->hctl; 1798 ip->mctl = myctladdr; 1799 myctladdr = op->mctl; 1800 ip->in = cin; 1801 cin = op->in; 1802 ip->out = cout; 1803 cout = op->out; 1804 ip->tpe = type; 1805 type = op->tpe; 1806 ip->curtpe = curtype; 1807 curtype = op->curtpe; 1808 ip->cpnd = cpend; 1809 cpend = op->cpnd; 1810 ip->sunqe = sunique; 1811 sunique = op->sunqe; 1812 ip->runqe = runique; 1813 runique = op->runqe; 1814 ip->mcse = mcase; 1815 mcase = op->mcse; 1816 ip->ntflg = ntflag; 1817 ntflag = op->ntflg; 1818 (void)strlcpy(ip->nti, ntin, sizeof(ip->nti)); 1819 (void)strlcpy(ntin, op->nti, sizeof ntin); 1820 (void)strlcpy(ip->nto, ntout, sizeof(ip->nto)); 1821 (void)strlcpy(ntout, op->nto, sizeof ntout); 1822 ip->mapflg = mapflag; 1823 mapflag = op->mapflg; 1824 (void)strlcpy(ip->mi, mapin, sizeof(ip->mi)); 1825 (void)strlcpy(mapin, op->mi, sizeof mapin); 1826 (void)strlcpy(ip->mo, mapout, sizeof(ip->mo)); 1827 (void)strlcpy(mapout, op->mo, sizeof mapout); 1828 (void)signal(SIGINT, oldintr); 1829 if (abrtflag) { 1830 abrtflag = 0; 1831 (*oldintr)(SIGINT); 1832 } 1833 } 1834 1835 /* ARGSUSED */ 1836 void 1837 abortpt(int signo) 1838 { 1839 1840 alarmtimer(0); 1841 putc('\n', ttyout); 1842 (void)fflush(ttyout); 1843 ptabflg++; 1844 mflag = 0; 1845 abrtflag = 0; 1846 longjmp(ptabort, 1); 1847 } 1848 1849 void 1850 proxtrans(const char *cmd, const char *local, const char *remote) 1851 { 1852 volatile sig_t oldintr; 1853 int prox_type, nfnd; 1854 volatile int secndflag; 1855 char * volatile cmd2; 1856 struct pollfd pfd[1]; 1857 1858 oldintr = NULL; 1859 secndflag = 0; 1860 if (strcmp(cmd, "RETR")) 1861 cmd2 = "RETR"; 1862 else 1863 cmd2 = runique ? "STOU" : "STOR"; 1864 if ((prox_type = type) == 0) { 1865 if (unix_server && unix_proxy) 1866 prox_type = TYPE_I; 1867 else 1868 prox_type = TYPE_A; 1869 } 1870 if (curtype != prox_type) 1871 changetype(prox_type, 1); 1872 if (command("PASV") != COMPLETE) { 1873 fputs("proxy server does not support third party transfers.\n", 1874 ttyout); 1875 return; 1876 } 1877 pswitch(0); 1878 if (!connected) { 1879 fputs("No primary connection.\n", ttyout); 1880 pswitch(1); 1881 code = -1; 1882 return; 1883 } 1884 if (curtype != prox_type) 1885 changetype(prox_type, 1); 1886 if (command("PORT %s", pasv) != COMPLETE) { 1887 pswitch(1); 1888 return; 1889 } 1890 if (setjmp(ptabort)) 1891 goto abort; 1892 oldintr = signal(SIGINT, abortpt); 1893 if (command("%s %s", cmd, remote) != PRELIM) { 1894 (void)signal(SIGINT, oldintr); 1895 pswitch(1); 1896 return; 1897 } 1898 sleep(2); 1899 pswitch(1); 1900 secndflag++; 1901 if (command("%s %s", cmd2, local) != PRELIM) 1902 goto abort; 1903 ptflag++; 1904 (void)getreply(0); 1905 pswitch(0); 1906 (void)getreply(0); 1907 (void)signal(SIGINT, oldintr); 1908 pswitch(1); 1909 ptflag = 0; 1910 fprintf(ttyout, "local: %s remote: %s\n", local, remote); 1911 return; 1912 abort: 1913 (void)signal(SIGINT, SIG_IGN); 1914 ptflag = 0; 1915 if (strcmp(cmd, "RETR") && !proxy) 1916 pswitch(1); 1917 else if (!strcmp(cmd, "RETR") && proxy) 1918 pswitch(0); 1919 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ 1920 if (command("%s %s", cmd2, local) != PRELIM) { 1921 pswitch(0); 1922 if (cpend) 1923 abort_remote(NULL); 1924 } 1925 pswitch(1); 1926 if (ptabflg) 1927 code = -1; 1928 (void)signal(SIGINT, oldintr); 1929 return; 1930 } 1931 if (cpend) 1932 abort_remote(NULL); 1933 pswitch(!proxy); 1934 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */ 1935 if (command("%s %s", cmd2, local) != PRELIM) { 1936 pswitch(0); 1937 if (cpend) 1938 abort_remote(NULL); 1939 pswitch(1); 1940 if (ptabflg) 1941 code = -1; 1942 (void)signal(SIGINT, oldintr); 1943 return; 1944 } 1945 } 1946 if (cpend) 1947 abort_remote(NULL); 1948 pswitch(!proxy); 1949 if (cpend) { 1950 pfd[0].fd = fileno(cin); 1951 pfd[0].events = POLLIN; 1952 if ((nfnd = poll(pfd, 1, 10 * 1000)) <= 0) { 1953 if (nfnd < 0) 1954 warn("abort"); 1955 if (ptabflg) 1956 code = -1; 1957 lostpeer(); 1958 } 1959 (void)getreply(0); 1960 (void)getreply(0); 1961 } 1962 if (proxy) 1963 pswitch(0); 1964 pswitch(1); 1965 if (ptabflg) 1966 code = -1; 1967 (void)signal(SIGINT, oldintr); 1968 } 1969 1970 #ifndef SMALL 1971 /* ARGSUSED */ 1972 void 1973 reset(int argc, char *argv[]) 1974 { 1975 struct pollfd pfd[1]; 1976 int nfnd = 1; 1977 1978 pfd[0].fd = fileno(cin); 1979 pfd[0].events = POLLIN; 1980 while (nfnd > 0) { 1981 if ((nfnd = poll(pfd, 1, 0)) < 0) { 1982 warn("reset"); 1983 code = -1; 1984 lostpeer(); 1985 } else if (nfnd) { 1986 (void)getreply(0); 1987 } 1988 } 1989 } 1990 #endif 1991 1992 char * 1993 gunique(const char *local) 1994 { 1995 static char new[MAXPATHLEN]; 1996 char *cp = strrchr(local, '/'); 1997 int d, count=0; 1998 char ext = '1'; 1999 2000 if (cp) 2001 *cp = '\0'; 2002 d = access(cp == local ? "/" : cp ? local : ".", W_OK); 2003 if (cp) 2004 *cp = '/'; 2005 if (d < 0) { 2006 warn("local: %s", local); 2007 return ((char *) 0); 2008 } 2009 (void)strlcpy(new, local, sizeof new); 2010 cp = new + strlen(new); 2011 *cp++ = '.'; 2012 while (!d) { 2013 if (++count == 100) { 2014 fputs("runique: can't find unique file name.\n", ttyout); 2015 return ((char *) 0); 2016 } 2017 *cp++ = ext; 2018 *cp = '\0'; 2019 if (ext == '9') 2020 ext = '0'; 2021 else 2022 ext++; 2023 if ((d = access(new, F_OK)) < 0) 2024 break; 2025 if (ext != '0') 2026 cp--; 2027 else if (*(cp - 2) == '.') 2028 *(cp - 1) = '1'; 2029 else { 2030 *(cp - 2) = *(cp - 2) + 1; 2031 cp--; 2032 } 2033 } 2034 return (new); 2035 } 2036 2037 jmp_buf forceabort; 2038 2039 /* ARGSUSED */ 2040 static void 2041 abortforce(int signo) 2042 { 2043 fputs("Forced abort. The connection will be closed.\n", ttyout); 2044 (void)fflush(ttyout); 2045 2046 if (cout) { 2047 (void)fclose(cout); 2048 } 2049 cout = NULL; 2050 2051 longjmp(forceabort, 1); 2052 } 2053 2054 void 2055 abort_remote(FILE *din) 2056 { 2057 char buf[BUFSIZ]; 2058 nfds_t nfds; 2059 int nfnd; 2060 struct pollfd pfd[2]; 2061 sig_t oldintr; 2062 2063 if (cout == NULL || setjmp(forceabort)) { 2064 warnx("Lost control connection for abort."); 2065 if (ptabflg) 2066 code = -1; 2067 lostpeer(); 2068 return; 2069 } 2070 2071 oldintr = signal(SIGINT, abortforce); 2072 2073 /* 2074 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark 2075 * after urgent byte rather than before as is protocol now 2076 */ 2077 snprintf(buf, sizeof buf, "%c%c%c", IAC, IP, IAC); 2078 if (send(fileno(cout), buf, 3, MSG_OOB) != 3) 2079 warn("abort"); 2080 fprintf(cout, "%cABOR\r\n", DM); 2081 (void)fflush(cout); 2082 pfd[0].fd = fileno(cin); 2083 pfd[0].events = POLLIN; 2084 nfds = 1; 2085 if (din) { 2086 pfd[1].fd = fileno(din); 2087 pfd[1].events = POLLIN; 2088 nfds++; 2089 } 2090 if ((nfnd = poll(pfd, nfds, 10 * 1000)) <= 0) { 2091 if (nfnd < 0) 2092 warn("abort"); 2093 if (ptabflg) 2094 code = -1; 2095 lostpeer(); 2096 } 2097 if (din && (pfd[1].revents & POLLIN)) { 2098 while (read(fileno(din), buf, BUFSIZ) > 0) 2099 /* LOOP */; 2100 } 2101 if (getreply(0) == ERROR && code == 552) { 2102 /* 552 needed for nic style abort */ 2103 (void)getreply(0); 2104 } 2105 (void)getreply(0); 2106 (void)signal(SIGINT, oldintr); 2107 } 2108