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