1 /* $OpenBSD: ftp.c,v 1.82 2012/04/30 13:41:26 haesbaert 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", gai_strerror(error), srcaddr); 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 void 382 send_noop_char() 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 void 397 may_reset_noop_timeout() 398 { 399 if (keep_alive_timeout != 0) 400 last_timestamp = time(NULL); 401 } 402 403 void 404 may_receive_noop_ack() 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 void 433 may_send_noop_char() 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 warnx("local: %s: %s", local, strerror(serrno)); 785 if (d < 0) { 786 if (serrno != EPIPE) 787 warnx("netout: %s", strerror(serrno)); 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 warnx("local: %s: %s", local, strerror(serrno)); 826 if (ferror(dout)) { 827 if (errno != EPIPE) 828 warnx("netout: %s", strerror(serrno)); 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 && errno == EPIPE) 1094 break; 1095 d += wr; 1096 rd -= wr; 1097 } while (d < c); 1098 if (rd != 0) 1099 break; 1100 bytes += c; 1101 if (hash && (!progress || filesize < 0)) { 1102 while (bytes >= hashbytes) { 1103 (void)putc('#', ttyout); 1104 hashbytes += mark; 1105 } 1106 (void)fflush(ttyout); 1107 } 1108 } 1109 if (c == -1 || d < c) 1110 serrno = errno; 1111 if (hash && (!progress || filesize < 0) && bytes > 0) { 1112 if (bytes < mark) 1113 (void)putc('#', ttyout); 1114 (void)putc('\n', ttyout); 1115 (void)fflush(ttyout); 1116 } 1117 if (c < 0) { 1118 if (serrno != EPIPE) 1119 warnx("netin: %s", strerror(serrno)); 1120 bytes = -1; 1121 } 1122 if (d < c) { 1123 if (d < 0) 1124 warnx("local: %s: %s", local, strerror(serrno)); 1125 else 1126 warnx("%s: short write", local); 1127 } 1128 break; 1129 1130 case TYPE_A: 1131 if (restart_point) { 1132 int i, n, ch; 1133 1134 if (fseek(fout, 0L, SEEK_SET) < 0) 1135 goto done; 1136 n = restart_point; 1137 for (i = 0; i++ < n;) { 1138 if ((ch = fgetc(fout)) == EOF) { 1139 if (!ferror(fout)) 1140 errno = 0; 1141 goto done; 1142 } 1143 if (ch == '\n') 1144 i++; 1145 } 1146 if (fseek(fout, 0L, SEEK_CUR) < 0) { 1147 done: 1148 if (errno) 1149 warn("local: %s", local); 1150 else 1151 warnx("local: %s", local); 1152 progress = oprogress; 1153 preserve = opreserve; 1154 if (closefunc != NULL) 1155 (*closefunc)(fout); 1156 return; 1157 } 1158 } 1159 while ((c = fgetc(din)) != EOF) { 1160 may_send_noop_char(); 1161 if (c == '\n') 1162 bare_lfs++; 1163 while (c == '\r') { 1164 while (hash && (!progress || filesize < 0) && 1165 (bytes >= hashbytes)) { 1166 (void)putc('#', ttyout); 1167 (void)fflush(ttyout); 1168 hashbytes += mark; 1169 } 1170 bytes++; 1171 if ((c = fgetc(din)) != '\n' || tcrflag) { 1172 if (ferror(fout)) 1173 goto break2; 1174 (void)putc('\r', fout); 1175 if (c == '\0') { 1176 bytes++; 1177 goto contin2; 1178 } 1179 if (c == EOF) 1180 goto contin2; 1181 } 1182 } 1183 (void)putc(c, fout); 1184 bytes++; 1185 contin2: ; 1186 } 1187 break2: 1188 if (ferror(din) || ferror(fout)) 1189 serrno = errno; 1190 if (bare_lfs) { 1191 fprintf(ttyout, 1192 "WARNING! %d bare linefeeds received in ASCII mode.\n", bare_lfs); 1193 fputs("File may not have transferred correctly.\n", 1194 ttyout); 1195 } 1196 if (hash && (!progress || filesize < 0)) { 1197 if (bytes < hashbytes) 1198 (void)putc('#', ttyout); 1199 (void)putc('\n', ttyout); 1200 (void)fflush(ttyout); 1201 } 1202 if (ferror(din)) { 1203 if (serrno != EPIPE) 1204 warnx("netin: %s", strerror(serrno)); 1205 bytes = -1; 1206 } 1207 if (ferror(fout)) 1208 warnx("local: %s: %s", local, strerror(serrno)); 1209 break; 1210 } 1211 progressmeter(1, NULL); 1212 progress = oprogress; 1213 preserve = opreserve; 1214 if (closefunc != NULL) 1215 (*closefunc)(fout); 1216 (void)signal(SIGINT, oldintr); 1217 (void)signal(SIGINFO, oldinti); 1218 if (oldintp) 1219 (void)signal(SIGPIPE, oldintp); 1220 (void)fclose(din); 1221 (void)getreply(0); 1222 may_receive_noop_ack(); 1223 if (bytes >= 0 && is_retr) { 1224 if (bytes > 0) 1225 ptransfer(0); 1226 if (preserve && (closefunc == fclose)) { 1227 mtime = remotemodtime(remote, 0); 1228 if (mtime != -1) { 1229 struct utimbuf ut; 1230 1231 ut.actime = time(NULL); 1232 ut.modtime = mtime; 1233 if (utime(local, &ut) == -1) 1234 fprintf(ttyout, 1235 "Can't change modification time on %s to %s", 1236 local, asctime(localtime(&mtime))); 1237 } 1238 } 1239 } 1240 return; 1241 1242 abort: 1243 /* abort using RFC959 recommended IP,SYNC sequence */ 1244 progress = oprogress; 1245 preserve = opreserve; 1246 if (oldintp) 1247 (void)signal(SIGPIPE, oldintp); 1248 (void)signal(SIGINT, SIG_IGN); 1249 if (!cpend) { 1250 code = -1; 1251 (void)signal(SIGINT, oldintr); 1252 (void)signal(SIGINFO, oldinti); 1253 return; 1254 } 1255 1256 abort_remote(din); 1257 code = -1; 1258 if (data >= 0) { 1259 (void)close(data); 1260 data = -1; 1261 } 1262 if (closefunc != NULL && fout != NULL) 1263 (*closefunc)(fout); 1264 if (din) 1265 (void)fclose(din); 1266 if (bytes > 0) 1267 ptransfer(0); 1268 (void)signal(SIGINT, oldintr); 1269 (void)signal(SIGINFO, oldinti); 1270 } 1271 1272 /* 1273 * Need to start a listen on the data channel before we send the command, 1274 * otherwise the server's connect may fail. 1275 */ 1276 int 1277 initconn(void) 1278 { 1279 char *p, *a; 1280 int result = ERROR, tmpno = 0; 1281 int on = 1; 1282 int error; 1283 u_int addr[16], port[2]; 1284 u_int af, hal, pal; 1285 char *pasvcmd = NULL; 1286 socklen_t namelen; 1287 struct addrinfo *ares; 1288 1289 if (myctladdr.su_family == AF_INET6 1290 && (IN6_IS_ADDR_LINKLOCAL(&myctladdr.su_sin6.sin6_addr) 1291 || IN6_IS_ADDR_SITELOCAL(&myctladdr.su_sin6.sin6_addr))) { 1292 warnx("use of scoped address can be troublesome"); 1293 } 1294 #ifndef SMALL 1295 if (srcaddr) { 1296 struct addrinfo ahints; 1297 1298 memset(&ahints, 0, sizeof(ahints)); 1299 ahints.ai_family = family; 1300 ahints.ai_socktype = SOCK_STREAM; 1301 ahints.ai_flags |= AI_NUMERICHOST; 1302 ahints.ai_protocol = 0; 1303 1304 error = getaddrinfo(srcaddr, NULL, &ahints, &ares); 1305 if (error) { 1306 warnx("%s: %s", gai_strerror(error), srcaddr); 1307 code = -1; 1308 return (0); 1309 } 1310 } 1311 #endif /* !SMALL */ 1312 reinit: 1313 if (passivemode) { 1314 data_addr = myctladdr; 1315 data = socket(data_addr.su_family, SOCK_STREAM, 0); 1316 if (data < 0) { 1317 warn("socket"); 1318 return (1); 1319 } 1320 #ifndef SMALL 1321 if (srcaddr) { 1322 if (bind(data, ares->ai_addr, ares->ai_addrlen) < 0) { 1323 warn("bind"); 1324 close(data); 1325 return (1); 1326 } 1327 } 1328 if ((options & SO_DEBUG) && 1329 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, 1330 sizeof(on)) < 0) 1331 warn("setsockopt (ignored)"); 1332 #endif /* !SMALL */ 1333 switch (data_addr.su_family) { 1334 case AF_INET: 1335 if (epsv4 && !epsv4bad) { 1336 int ov; 1337 /* shut this command up in case it fails */ 1338 ov = verbose; 1339 verbose = -1; 1340 result = command(pasvcmd = "EPSV"); 1341 /* 1342 * now back to whatever verbosity we had before 1343 * and we can try PASV 1344 */ 1345 verbose = ov; 1346 if (code / 10 == 22 && code != 229) { 1347 fputs( 1348 "wrong server: return code must be 229\n", 1349 ttyout); 1350 result = COMPLETE + 1; 1351 } 1352 if (result != COMPLETE) { 1353 epsv4bad = 1; 1354 #ifndef SMALL 1355 if (debug) { 1356 fputs( 1357 "disabling epsv4 for this connection\n", 1358 ttyout); 1359 } 1360 #endif /* !SMALL */ 1361 } 1362 } 1363 if (result != COMPLETE) 1364 result = command(pasvcmd = "PASV"); 1365 break; 1366 case AF_INET6: 1367 result = command(pasvcmd = "EPSV"); 1368 if (code / 10 == 22 && code != 229) { 1369 fputs( 1370 "wrong server: return code must be 229\n", 1371 ttyout); 1372 result = COMPLETE + 1; 1373 } 1374 if (result != COMPLETE) 1375 result = command(pasvcmd = "LPSV"); 1376 break; 1377 default: 1378 result = COMPLETE + 1; 1379 break; 1380 } 1381 if (result != COMPLETE) { 1382 if (activefallback) { 1383 (void)close(data); 1384 data = -1; 1385 passivemode = 0; 1386 activefallback = 0; 1387 goto reinit; 1388 } 1389 fputs("Passive mode refused.\n", ttyout); 1390 goto bad; 1391 } 1392 1393 #define pack2(var, off) \ 1394 (((var[(off) + 0] & 0xff) << 8) | ((var[(off) + 1] & 0xff) << 0)) 1395 #define pack4(var, off) \ 1396 (((var[(off) + 0] & 0xff) << 24) | ((var[(off) + 1] & 0xff) << 16) | \ 1397 ((var[(off) + 2] & 0xff) << 8) | ((var[(off) + 3] & 0xff) << 0)) 1398 1399 /* 1400 * What we've got at this point is a string of comma separated 1401 * one-byte unsigned integer values, separated by commas. 1402 */ 1403 if (!pasvcmd) 1404 goto bad; 1405 if (strcmp(pasvcmd, "PASV") == 0) { 1406 if (data_addr.su_family != AF_INET) { 1407 fputs( 1408 "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); 1409 error = 1; 1410 goto bad; 1411 } 1412 if (code / 10 == 22 && code != 227) { 1413 fputs("wrong server: return code must be 227\n", 1414 ttyout); 1415 error = 1; 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 error = 1; 1425 goto bad; 1426 } 1427 error = 0; 1428 memset(&data_addr, 0, sizeof(data_addr)); 1429 data_addr.su_family = AF_INET; 1430 data_addr.su_len = sizeof(struct sockaddr_in); 1431 data_addr.su_sin.sin_addr.s_addr = 1432 htonl(pack4(addr, 0)); 1433 data_addr.su_port = htons(pack2(port, 0)); 1434 } else if (strcmp(pasvcmd, "LPSV") == 0) { 1435 if (code / 10 == 22 && code != 228) { 1436 fputs("wrong server: return code must be 228\n", 1437 ttyout); 1438 error = 1; 1439 goto bad; 1440 } 1441 switch (data_addr.su_family) { 1442 case AF_INET: 1443 error = sscanf(pasv, 1444 "%u,%u,%u,%u,%u,%u,%u,%u,%u", 1445 &af, &hal, 1446 &addr[0], &addr[1], &addr[2], &addr[3], 1447 &pal, &port[0], &port[1]); 1448 if (error != 9) { 1449 fputs( 1450 "Passive mode address scan failure. Shouldn't happen!\n", ttyout); 1451 error = 1; 1452 goto bad; 1453 } 1454 if (af != 4 || hal != 4 || pal != 2) { 1455 fputs( 1456 "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); 1457 error = 1; 1458 goto bad; 1459 } 1460 1461 error = 0; 1462 memset(&data_addr, 0, sizeof(data_addr)); 1463 data_addr.su_family = AF_INET; 1464 data_addr.su_len = sizeof(struct sockaddr_in); 1465 data_addr.su_sin.sin_addr.s_addr = 1466 htonl(pack4(addr, 0)); 1467 data_addr.su_port = htons(pack2(port, 0)); 1468 break; 1469 case AF_INET6: 1470 error = sscanf(pasv, 1471 "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", 1472 &af, &hal, 1473 &addr[0], &addr[1], &addr[2], &addr[3], 1474 &addr[4], &addr[5], &addr[6], &addr[7], 1475 &addr[8], &addr[9], &addr[10], 1476 &addr[11], &addr[12], &addr[13], 1477 &addr[14], &addr[15], 1478 &pal, &port[0], &port[1]); 1479 if (error != 21) { 1480 fputs( 1481 "Passive mode address scan failure. Shouldn't happen!\n", ttyout); 1482 error = 1; 1483 goto bad; 1484 } 1485 if (af != 6 || hal != 16 || pal != 2) { 1486 fputs( 1487 "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); 1488 error = 1; 1489 goto bad; 1490 } 1491 1492 error = 0; 1493 memset(&data_addr, 0, sizeof(data_addr)); 1494 data_addr.su_family = AF_INET6; 1495 data_addr.su_len = sizeof(struct sockaddr_in6); 1496 { 1497 u_int32_t *p32; 1498 p32 = (u_int32_t *)&data_addr.su_sin6.sin6_addr; 1499 p32[0] = htonl(pack4(addr, 0)); 1500 p32[1] = htonl(pack4(addr, 4)); 1501 p32[2] = htonl(pack4(addr, 8)); 1502 p32[3] = htonl(pack4(addr, 12)); 1503 } 1504 data_addr.su_port = htons(pack2(port, 0)); 1505 break; 1506 default: 1507 error = 1; 1508 } 1509 } else if (strcmp(pasvcmd, "EPSV") == 0) { 1510 char delim[4]; 1511 1512 port[0] = 0; 1513 if (code / 10 == 22 && code != 229) { 1514 fputs("wrong server: return code must be 229\n", 1515 ttyout); 1516 error = 1; 1517 goto bad; 1518 } 1519 if (sscanf(pasv, "%c%c%c%d%c", &delim[0], 1520 &delim[1], &delim[2], &port[1], 1521 &delim[3]) != 5) { 1522 fputs("parse error!\n", ttyout); 1523 error = 1; 1524 goto bad; 1525 } 1526 if (delim[0] != delim[1] || delim[0] != delim[2] 1527 || delim[0] != delim[3]) { 1528 fputs("parse error!\n", ttyout); 1529 error = 1; 1530 goto bad; 1531 } 1532 data_addr = hisctladdr; 1533 data_addr.su_port = htons(port[1]); 1534 } else 1535 goto bad; 1536 1537 while (connect(data, (struct sockaddr *)&data_addr, 1538 data_addr.su_len) < 0) { 1539 if (errno == EINTR) 1540 continue; 1541 if (activefallback) { 1542 (void)close(data); 1543 data = -1; 1544 passivemode = 0; 1545 activefallback = 0; 1546 goto reinit; 1547 } 1548 warn("connect"); 1549 goto bad; 1550 } 1551 #if defined(IPPROTO_IP) && defined(IP_TOS) 1552 if (data_addr.su_family == AF_INET) { 1553 on = IPTOS_THROUGHPUT; 1554 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, 1555 sizeof(int)) < 0) 1556 warn("setsockopt TOS (ignored)"); 1557 } 1558 #endif 1559 return (0); 1560 } 1561 1562 noport: 1563 data_addr = myctladdr; 1564 if (sendport) 1565 data_addr.su_port = 0; /* let system pick one */ 1566 if (data != -1) 1567 (void)close(data); 1568 data = socket(data_addr.su_family, SOCK_STREAM, 0); 1569 if (data < 0) { 1570 warn("socket"); 1571 if (tmpno) 1572 sendport = 1; 1573 return (1); 1574 } 1575 if (!sendport) 1576 if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, 1577 sizeof(on)) < 0) { 1578 warn("setsockopt (reuse address)"); 1579 goto bad; 1580 } 1581 switch (data_addr.su_family) { 1582 case AF_INET: 1583 on = IP_PORTRANGE_HIGH; 1584 if (setsockopt(data, IPPROTO_IP, IP_PORTRANGE, 1585 (char *)&on, sizeof(on)) < 0) 1586 warn("setsockopt IP_PORTRANGE (ignored)"); 1587 break; 1588 case AF_INET6: 1589 on = IPV6_PORTRANGE_HIGH; 1590 if (setsockopt(data, IPPROTO_IPV6, IPV6_PORTRANGE, 1591 (char *)&on, sizeof(on)) < 0) 1592 warn("setsockopt IPV6_PORTRANGE (ignored)"); 1593 break; 1594 } 1595 if (bind(data, (struct sockaddr *)&data_addr, data_addr.su_len) < 0) { 1596 warn("bind"); 1597 goto bad; 1598 } 1599 #ifndef SMALL 1600 if (options & SO_DEBUG && 1601 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, 1602 sizeof(on)) < 0) 1603 warn("setsockopt (ignored)"); 1604 #endif /* !SMALL */ 1605 namelen = sizeof(data_addr); 1606 if (getsockname(data, (struct sockaddr *)&data_addr, &namelen) < 0) { 1607 warn("getsockname"); 1608 goto bad; 1609 } 1610 if (listen(data, 1) < 0) 1611 warn("listen"); 1612 1613 #define UC(b) (((int)b)&0xff) 1614 1615 if (sendport) { 1616 char hname[NI_MAXHOST], pbuf[NI_MAXSERV]; 1617 int af_tmp; 1618 union sockunion tmp; 1619 1620 tmp = data_addr; 1621 switch (tmp.su_family) { 1622 case AF_INET: 1623 if (!epsv4 || epsv4bad) { 1624 result = COMPLETE +1; 1625 break; 1626 } 1627 /*FALLTHROUGH*/ 1628 case AF_INET6: 1629 if (tmp.su_family == AF_INET6) 1630 tmp.su_sin6.sin6_scope_id = 0; 1631 af_tmp = (tmp.su_family == AF_INET) ? 1 : 2; 1632 if (getnameinfo((struct sockaddr *)&tmp, 1633 tmp.su_len, hname, sizeof(hname), 1634 pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { 1635 result = ERROR; 1636 } else { 1637 result = command("EPRT |%d|%s|%s|", 1638 af_tmp, hname, pbuf); 1639 if (result != COMPLETE) { 1640 epsv4bad = 1; 1641 #ifndef SMALL 1642 if (debug) { 1643 fputs( 1644 "disabling epsv4 for this connection\n", 1645 ttyout); 1646 } 1647 #endif /* !SMALL */ 1648 } 1649 } 1650 break; 1651 default: 1652 result = COMPLETE + 1; 1653 break; 1654 } 1655 if (result == COMPLETE) 1656 goto skip_port; 1657 1658 switch (data_addr.su_family) { 1659 case AF_INET: 1660 a = (char *)&data_addr.su_sin.sin_addr; 1661 p = (char *)&data_addr.su_port; 1662 result = command("PORT %d,%d,%d,%d,%d,%d", 1663 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 1664 UC(p[0]), UC(p[1])); 1665 break; 1666 case AF_INET6: 1667 a = (char *)&data_addr.su_sin6.sin6_addr; 1668 p = (char *)&data_addr.su_port; 1669 result = command( 1670 "LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", 1671 6, 16, 1672 UC(a[0]),UC(a[1]),UC(a[2]),UC(a[3]), 1673 UC(a[4]),UC(a[5]),UC(a[6]),UC(a[7]), 1674 UC(a[8]),UC(a[9]),UC(a[10]),UC(a[11]), 1675 UC(a[12]),UC(a[13]),UC(a[14]),UC(a[15]), 1676 2, UC(p[0]), UC(p[1])); 1677 break; 1678 default: 1679 result = COMPLETE + 1; /* xxx */ 1680 } 1681 skip_port: 1682 1683 if (result == ERROR && sendport == -1) { 1684 sendport = 0; 1685 tmpno = 1; 1686 goto noport; 1687 } 1688 return (result != COMPLETE); 1689 } 1690 if (tmpno) 1691 sendport = 1; 1692 #if defined(IPPROTO_IP) && defined(IP_TOS) 1693 if (data_addr.su_family == AF_INET) { 1694 on = IPTOS_THROUGHPUT; 1695 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, 1696 sizeof(int)) < 0) 1697 warn("setsockopt TOS (ignored)"); 1698 } 1699 #endif 1700 return (0); 1701 bad: 1702 (void)close(data), data = -1; 1703 if (tmpno) 1704 sendport = 1; 1705 return (1); 1706 } 1707 1708 FILE * 1709 dataconn(const char *lmode) 1710 { 1711 union sockunion from; 1712 socklen_t fromlen = myctladdr.su_len; 1713 int s; 1714 1715 if (passivemode) 1716 return (fdopen(data, lmode)); 1717 1718 s = accept(data, (struct sockaddr *) &from, &fromlen); 1719 if (s < 0) { 1720 warn("accept"); 1721 (void)close(data), data = -1; 1722 return (NULL); 1723 } 1724 (void)close(data); 1725 data = s; 1726 #if defined(IPPROTO_IP) && defined(IP_TOS) 1727 if (from.su_family == AF_INET) { 1728 int tos = IPTOS_THROUGHPUT; 1729 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, 1730 sizeof(int)) < 0) { 1731 warn("setsockopt TOS (ignored)"); 1732 } 1733 } 1734 #endif 1735 return (fdopen(data, lmode)); 1736 } 1737 1738 /* ARGSUSED */ 1739 void 1740 psummary(int signo) 1741 { 1742 int save_errno = errno; 1743 1744 if (bytes > 0) 1745 ptransfer(1); 1746 errno = save_errno; 1747 } 1748 1749 /* ARGSUSED */ 1750 void 1751 psabort(int signo) 1752 { 1753 1754 alarmtimer(0); 1755 abrtflag++; 1756 } 1757 1758 void 1759 pswitch(int flag) 1760 { 1761 sig_t oldintr; 1762 static struct comvars { 1763 int connect; 1764 char name[MAXHOSTNAMELEN]; 1765 union sockunion mctl; 1766 union sockunion hctl; 1767 FILE *in; 1768 FILE *out; 1769 int tpe; 1770 int curtpe; 1771 int cpnd; 1772 int sunqe; 1773 int runqe; 1774 int mcse; 1775 int ntflg; 1776 char nti[17]; 1777 char nto[17]; 1778 int mapflg; 1779 char mi[MAXPATHLEN]; 1780 char mo[MAXPATHLEN]; 1781 } proxstruct, tmpstruct; 1782 struct comvars *ip, *op; 1783 1784 abrtflag = 0; 1785 oldintr = signal(SIGINT, psabort); 1786 if (flag) { 1787 if (proxy) 1788 return; 1789 ip = &tmpstruct; 1790 op = &proxstruct; 1791 proxy++; 1792 } else { 1793 if (!proxy) 1794 return; 1795 ip = &proxstruct; 1796 op = &tmpstruct; 1797 proxy = 0; 1798 } 1799 ip->connect = connected; 1800 connected = op->connect; 1801 if (hostname) { 1802 (void)strlcpy(ip->name, hostname, sizeof(ip->name)); 1803 } else 1804 ip->name[0] = '\0'; 1805 hostname = op->name; 1806 ip->hctl = hisctladdr; 1807 hisctladdr = op->hctl; 1808 ip->mctl = myctladdr; 1809 myctladdr = op->mctl; 1810 ip->in = cin; 1811 cin = op->in; 1812 ip->out = cout; 1813 cout = op->out; 1814 ip->tpe = type; 1815 type = op->tpe; 1816 ip->curtpe = curtype; 1817 curtype = op->curtpe; 1818 ip->cpnd = cpend; 1819 cpend = op->cpnd; 1820 ip->sunqe = sunique; 1821 sunique = op->sunqe; 1822 ip->runqe = runique; 1823 runique = op->runqe; 1824 ip->mcse = mcase; 1825 mcase = op->mcse; 1826 ip->ntflg = ntflag; 1827 ntflag = op->ntflg; 1828 (void)strlcpy(ip->nti, ntin, sizeof(ip->nti)); 1829 (void)strlcpy(ntin, op->nti, sizeof ntin); 1830 (void)strlcpy(ip->nto, ntout, sizeof(ip->nto)); 1831 (void)strlcpy(ntout, op->nto, sizeof ntout); 1832 ip->mapflg = mapflag; 1833 mapflag = op->mapflg; 1834 (void)strlcpy(ip->mi, mapin, sizeof(ip->mi)); 1835 (void)strlcpy(mapin, op->mi, sizeof mapin); 1836 (void)strlcpy(ip->mo, mapout, sizeof(ip->mo)); 1837 (void)strlcpy(mapout, op->mo, sizeof mapout); 1838 (void)signal(SIGINT, oldintr); 1839 if (abrtflag) { 1840 abrtflag = 0; 1841 (*oldintr)(SIGINT); 1842 } 1843 } 1844 1845 /* ARGSUSED */ 1846 void 1847 abortpt(int signo) 1848 { 1849 1850 alarmtimer(0); 1851 putc('\n', ttyout); 1852 (void)fflush(ttyout); 1853 ptabflg++; 1854 mflag = 0; 1855 abrtflag = 0; 1856 longjmp(ptabort, 1); 1857 } 1858 1859 void 1860 proxtrans(const char *cmd, const char *local, const char *remote) 1861 { 1862 volatile sig_t oldintr; 1863 int prox_type, nfnd; 1864 volatile int secndflag; 1865 char * volatile cmd2; 1866 struct pollfd pfd[1]; 1867 1868 oldintr = NULL; 1869 secndflag = 0; 1870 if (strcmp(cmd, "RETR")) 1871 cmd2 = "RETR"; 1872 else 1873 cmd2 = runique ? "STOU" : "STOR"; 1874 if ((prox_type = type) == 0) { 1875 if (unix_server && unix_proxy) 1876 prox_type = TYPE_I; 1877 else 1878 prox_type = TYPE_A; 1879 } 1880 if (curtype != prox_type) 1881 changetype(prox_type, 1); 1882 if (command("PASV") != COMPLETE) { 1883 fputs("proxy server does not support third party transfers.\n", 1884 ttyout); 1885 return; 1886 } 1887 pswitch(0); 1888 if (!connected) { 1889 fputs("No primary connection.\n", ttyout); 1890 pswitch(1); 1891 code = -1; 1892 return; 1893 } 1894 if (curtype != prox_type) 1895 changetype(prox_type, 1); 1896 if (command("PORT %s", pasv) != COMPLETE) { 1897 pswitch(1); 1898 return; 1899 } 1900 if (setjmp(ptabort)) 1901 goto abort; 1902 oldintr = signal(SIGINT, abortpt); 1903 if (command("%s %s", cmd, remote) != PRELIM) { 1904 (void)signal(SIGINT, oldintr); 1905 pswitch(1); 1906 return; 1907 } 1908 sleep(2); 1909 pswitch(1); 1910 secndflag++; 1911 if (command("%s %s", cmd2, local) != PRELIM) 1912 goto abort; 1913 ptflag++; 1914 (void)getreply(0); 1915 pswitch(0); 1916 (void)getreply(0); 1917 (void)signal(SIGINT, oldintr); 1918 pswitch(1); 1919 ptflag = 0; 1920 fprintf(ttyout, "local: %s remote: %s\n", local, remote); 1921 return; 1922 abort: 1923 (void)signal(SIGINT, SIG_IGN); 1924 ptflag = 0; 1925 if (strcmp(cmd, "RETR") && !proxy) 1926 pswitch(1); 1927 else if (!strcmp(cmd, "RETR") && proxy) 1928 pswitch(0); 1929 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ 1930 if (command("%s %s", cmd2, local) != PRELIM) { 1931 pswitch(0); 1932 if (cpend) 1933 abort_remote(NULL); 1934 } 1935 pswitch(1); 1936 if (ptabflg) 1937 code = -1; 1938 (void)signal(SIGINT, oldintr); 1939 return; 1940 } 1941 if (cpend) 1942 abort_remote(NULL); 1943 pswitch(!proxy); 1944 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */ 1945 if (command("%s %s", cmd2, local) != PRELIM) { 1946 pswitch(0); 1947 if (cpend) 1948 abort_remote(NULL); 1949 pswitch(1); 1950 if (ptabflg) 1951 code = -1; 1952 (void)signal(SIGINT, oldintr); 1953 return; 1954 } 1955 } 1956 if (cpend) 1957 abort_remote(NULL); 1958 pswitch(!proxy); 1959 if (cpend) { 1960 pfd[0].fd = fileno(cin); 1961 pfd[0].events = POLLIN; 1962 if ((nfnd = poll(pfd, 1, 10 * 1000)) <= 0) { 1963 if (nfnd < 0) 1964 warn("abort"); 1965 if (ptabflg) 1966 code = -1; 1967 lostpeer(); 1968 } 1969 (void)getreply(0); 1970 (void)getreply(0); 1971 } 1972 if (proxy) 1973 pswitch(0); 1974 pswitch(1); 1975 if (ptabflg) 1976 code = -1; 1977 (void)signal(SIGINT, oldintr); 1978 } 1979 1980 #ifndef SMALL 1981 /* ARGSUSED */ 1982 void 1983 reset(int argc, char *argv[]) 1984 { 1985 struct pollfd pfd[1]; 1986 int nfnd = 1; 1987 1988 pfd[0].fd = fileno(cin); 1989 pfd[0].events = POLLIN; 1990 while (nfnd > 0) { 1991 if ((nfnd = poll(pfd, 1, 0)) < 0) { 1992 warn("reset"); 1993 code = -1; 1994 lostpeer(); 1995 } else if (nfnd) { 1996 (void)getreply(0); 1997 } 1998 } 1999 } 2000 #endif 2001 2002 char * 2003 gunique(const char *local) 2004 { 2005 static char new[MAXPATHLEN]; 2006 char *cp = strrchr(local, '/'); 2007 int d, count=0; 2008 char ext = '1'; 2009 2010 if (cp) 2011 *cp = '\0'; 2012 d = access(cp == local ? "/" : cp ? local : ".", W_OK); 2013 if (cp) 2014 *cp = '/'; 2015 if (d < 0) { 2016 warn("local: %s", local); 2017 return ((char *) 0); 2018 } 2019 (void)strlcpy(new, local, sizeof new); 2020 cp = new + strlen(new); 2021 *cp++ = '.'; 2022 while (!d) { 2023 if (++count == 100) { 2024 fputs("runique: can't find unique file name.\n", ttyout); 2025 return ((char *) 0); 2026 } 2027 *cp++ = ext; 2028 *cp = '\0'; 2029 if (ext == '9') 2030 ext = '0'; 2031 else 2032 ext++; 2033 if ((d = access(new, F_OK)) < 0) 2034 break; 2035 if (ext != '0') 2036 cp--; 2037 else if (*(cp - 2) == '.') 2038 *(cp - 1) = '1'; 2039 else { 2040 *(cp - 2) = *(cp - 2) + 1; 2041 cp--; 2042 } 2043 } 2044 return (new); 2045 } 2046 2047 jmp_buf forceabort; 2048 2049 /* ARGSUSED */ 2050 void 2051 abortforce(int signo) 2052 { 2053 fputs("Forced abort. The connection will be closed.\n", ttyout); 2054 (void)fflush(ttyout); 2055 2056 if (cout) { 2057 (void)fclose(cout); 2058 } 2059 cout = NULL; 2060 2061 longjmp(forceabort, 1); 2062 } 2063 2064 void 2065 abort_remote(FILE *din) 2066 { 2067 char buf[BUFSIZ]; 2068 nfds_t nfds; 2069 int nfnd; 2070 struct pollfd pfd[2]; 2071 sig_t oldintr; 2072 2073 if (cout == NULL || setjmp(forceabort)) { 2074 warnx("Lost control connection for abort."); 2075 if (ptabflg) 2076 code = -1; 2077 lostpeer(); 2078 return; 2079 } 2080 2081 oldintr = signal(SIGINT, abortforce); 2082 2083 /* 2084 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark 2085 * after urgent byte rather than before as is protocol now 2086 */ 2087 snprintf(buf, sizeof buf, "%c%c%c", IAC, IP, IAC); 2088 if (send(fileno(cout), buf, 3, MSG_OOB) != 3) 2089 warn("abort"); 2090 fprintf(cout, "%cABOR\r\n", DM); 2091 (void)fflush(cout); 2092 pfd[0].fd = fileno(cin); 2093 pfd[0].events = POLLIN; 2094 nfds = 1; 2095 if (din) { 2096 pfd[1].fd = fileno(din); 2097 pfd[1].events = POLLIN; 2098 nfds++; 2099 } 2100 if ((nfnd = poll(pfd, nfds, 10 * 1000)) <= 0) { 2101 if (nfnd < 0) 2102 warn("abort"); 2103 if (ptabflg) 2104 code = -1; 2105 lostpeer(); 2106 } 2107 if (din && (pfd[1].revents & POLLIN)) { 2108 while (read(fileno(din), buf, BUFSIZ) > 0) 2109 /* LOOP */; 2110 } 2111 if (getreply(0) == ERROR && code == 552) { 2112 /* 552 needed for nic style abort */ 2113 (void)getreply(0); 2114 } 2115 (void)getreply(0); 2116 (void)signal(SIGINT, oldintr); 2117 } 2118