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