1 /* $NetBSD: ftp.c,v 1.155 2008/04/28 20:24:13 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 1996-2008 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.155 2008/04/28 20:24:13 martin 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(char *host, 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, line; 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 (line = 0 ;; line++) { 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 (line == 0) 484 (void)strlcpy(reply_string, current_line, 485 sizeof(reply_string)); 486 if (line > 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 *cin, FILE *din, int sec) 511 { 512 int nr, nfd; 513 struct pollfd pfd[2]; 514 515 nfd = 0; 516 if (cin) { 517 pfd[nfd].fd = fileno(cin); 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 (cin) 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(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 char *volatile 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 (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 RFC0959 */ 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 (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 RFC0959 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 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 pasvcmd = "EPSV"; 1269 overbose = verbose; 1270 if (ftp_debug == 0) 1271 verbose = -1; 1272 result = command("EPSV"); 1273 verbose = overbose; 1274 if (verbose > 0 && 1275 (result == COMPLETE || !connected)) 1276 fprintf(ttyout, "%s\n", reply_string); 1277 if (!connected) 1278 return (1); 1279 /* this code is to be friendly with broken BSDI ftpd */ 1280 if (code / 10 == 22 && code != 229) { 1281 fputs( 1282 "wrong server: return code must be 229\n", 1283 ttyout); 1284 result = COMPLETE + 1; 1285 } 1286 if (result != COMPLETE) { 1287 pasvcmd = "LPSV"; 1288 result = command("LPSV"); 1289 } 1290 if (!connected) 1291 return (1); 1292 break; 1293 #endif 1294 default: 1295 result = COMPLETE + 1; 1296 break; 1297 } 1298 if (result != COMPLETE) { 1299 if (activefallback) { 1300 (void)close(data); 1301 data = -1; 1302 passivemode = 0; 1303 #if 0 1304 activefallback = 0; 1305 #endif 1306 goto reinit; 1307 } 1308 fputs("Passive mode refused.\n", ttyout); 1309 goto bad; 1310 } 1311 1312 #define pack2(var, off) \ 1313 (((var[(off) + 0] & 0xff) << 8) | ((var[(off) + 1] & 0xff) << 0)) 1314 #define pack4(var, off) \ 1315 (((var[(off) + 0] & 0xff) << 24) | ((var[(off) + 1] & 0xff) << 16) | \ 1316 ((var[(off) + 2] & 0xff) << 8) | ((var[(off) + 3] & 0xff) << 0)) 1317 #define UC(b) (((int)b)&0xff) 1318 1319 /* 1320 * What we've got at this point is a string of comma separated 1321 * one-byte unsigned integer values, separated by commas. 1322 */ 1323 if (strcmp(pasvcmd, "PASV") == 0) { 1324 if (data_addr.su_family != AF_INET) { 1325 fputs( 1326 "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); 1327 error = 1; 1328 goto bad; 1329 } 1330 if (code / 10 == 22 && code != 227) { 1331 fputs("wrong server: return code must be 227\n", 1332 ttyout); 1333 error = 1; 1334 goto bad; 1335 } 1336 error = sscanf(pasv, "%u,%u,%u,%u,%u,%u", 1337 &addr[0], &addr[1], &addr[2], &addr[3], 1338 &port[0], &port[1]); 1339 if (error != 6) { 1340 fputs( 1341 "Passive mode address scan failure. Shouldn't happen!\n", ttyout); 1342 error = 1; 1343 goto bad; 1344 } 1345 error = 0; 1346 memset(&data_addr, 0, sizeof(data_addr)); 1347 data_addr.su_family = AF_INET; 1348 data_addr.su_len = sizeof(struct sockaddr_in); 1349 data_addr.si_su.su_sin.sin_addr.s_addr = 1350 htonl(pack4(addr, 0)); 1351 data_addr.su_port = htons(pack2(port, 0)); 1352 } else if (strcmp(pasvcmd, "LPSV") == 0) { 1353 if (code / 10 == 22 && code != 228) { 1354 fputs("wrong server: return code must be 228\n", 1355 ttyout); 1356 error = 1; 1357 goto bad; 1358 } 1359 switch (data_addr.su_family) { 1360 case AF_INET: 1361 error = sscanf(pasv, 1362 "%u,%u,%u,%u,%u,%u,%u,%u,%u", 1363 &af, &hal, 1364 &addr[0], &addr[1], &addr[2], &addr[3], 1365 &pal, &port[0], &port[1]); 1366 if (error != 9) { 1367 fputs( 1368 "Passive mode address scan failure. Shouldn't happen!\n", ttyout); 1369 error = 1; 1370 goto bad; 1371 } 1372 if (af != 4 || hal != 4 || pal != 2) { 1373 fputs( 1374 "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); 1375 error = 1; 1376 goto bad; 1377 } 1378 1379 error = 0; 1380 memset(&data_addr, 0, sizeof(data_addr)); 1381 data_addr.su_family = AF_INET; 1382 data_addr.su_len = sizeof(struct sockaddr_in); 1383 data_addr.si_su.su_sin.sin_addr.s_addr = 1384 htonl(pack4(addr, 0)); 1385 data_addr.su_port = htons(pack2(port, 0)); 1386 break; 1387 #ifdef INET6 1388 case AF_INET6: 1389 error = sscanf(pasv, 1390 "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", 1391 &af, &hal, 1392 &addr[0], &addr[1], &addr[2], &addr[3], 1393 &addr[4], &addr[5], &addr[6], &addr[7], 1394 &addr[8], &addr[9], &addr[10], 1395 &addr[11], &addr[12], &addr[13], 1396 &addr[14], &addr[15], 1397 &pal, &port[0], &port[1]); 1398 if (error != 21) { 1399 fputs( 1400 "Passive mode address scan failure. Shouldn't happen!\n", ttyout); 1401 error = 1; 1402 goto bad; 1403 } 1404 if (af != 6 || hal != 16 || pal != 2) { 1405 fputs( 1406 "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); 1407 error = 1; 1408 goto bad; 1409 } 1410 1411 error = 0; 1412 memset(&data_addr, 0, sizeof(data_addr)); 1413 data_addr.su_family = AF_INET6; 1414 data_addr.su_len = sizeof(struct sockaddr_in6); 1415 { 1416 int i; 1417 for (i = 0; i < sizeof(struct in6_addr); i++) { 1418 data_addr.si_su.su_sin6.sin6_addr.s6_addr[i] = 1419 UC(addr[i]); 1420 } 1421 } 1422 data_addr.su_port = htons(pack2(port, 0)); 1423 break; 1424 #endif 1425 default: 1426 error = 1; 1427 } 1428 } else if (strcmp(pasvcmd, "EPSV") == 0) { 1429 char delim[4]; 1430 1431 port[0] = 0; 1432 if (code / 10 == 22 && code != 229) { 1433 fputs("wrong server: return code must be 229\n", 1434 ttyout); 1435 error = 1; 1436 goto bad; 1437 } 1438 if (sscanf(pasv, "%c%c%c%d%c", &delim[0], 1439 &delim[1], &delim[2], &port[1], 1440 &delim[3]) != 5) { 1441 fputs("parse error!\n", ttyout); 1442 error = 1; 1443 goto bad; 1444 } 1445 if (delim[0] != delim[1] || delim[0] != delim[2] 1446 || delim[0] != delim[3]) { 1447 fputs("parse error!\n", ttyout); 1448 error = 1; 1449 goto bad; 1450 } 1451 data_addr = hisctladdr; 1452 data_addr.su_port = htons(port[1]); 1453 } else 1454 goto bad; 1455 1456 if (ftp_connect(data, (struct sockaddr *)&data_addr.si_su, 1457 data_addr.su_len) < 0) { 1458 if (activefallback) { 1459 (void)close(data); 1460 data = -1; 1461 passivemode = 0; 1462 #if 0 1463 activefallback = 0; 1464 #endif 1465 goto reinit; 1466 } 1467 goto bad; 1468 } 1469 #ifdef IPTOS_THROUGHPUT 1470 if (data_addr.su_family == AF_INET) { 1471 on = IPTOS_THROUGHPUT; 1472 if (setsockopt(data, IPPROTO_IP, IP_TOS, 1473 (void *)&on, sizeof(on)) == -1) { 1474 DWARN("setsockopt %s (ignored)", 1475 "IPTOS_THROUGHPUT"); 1476 } 1477 } 1478 #endif 1479 return (0); 1480 } 1481 1482 noport: 1483 data_addr = myctladdr; 1484 if (sendport) 1485 data_addr.su_port = 0; /* let system pick one */ 1486 if (data != -1) 1487 (void)close(data); 1488 data = socket(data_addr.su_family, SOCK_STREAM, 0); 1489 if (data < 0) { 1490 warn("Can't create socket for data connection"); 1491 if (tmpno) 1492 sendport = 1; 1493 return (1); 1494 } 1495 if (!sendport) 1496 if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, 1497 (void *)&on, sizeof(on)) == -1) { 1498 warn("Can't set SO_REUSEADDR on data connection"); 1499 goto bad; 1500 } 1501 if (bind(data, (struct sockaddr *)&data_addr.si_su, 1502 data_addr.su_len) < 0) { 1503 warn("Can't bind for data connection"); 1504 goto bad; 1505 } 1506 if ((options & SO_DEBUG) && 1507 setsockopt(data, SOL_SOCKET, SO_DEBUG, 1508 (void *)&on, sizeof(on)) == -1) { 1509 DWARN("setsockopt %s (ignored)", "SO_DEBUG"); 1510 } 1511 len = sizeof(data_addr.si_su); 1512 memset((char *)&data_addr, 0, sizeof (data_addr)); 1513 if (getsockname(data, (struct sockaddr *)&data_addr.si_su, &len) == -1) { 1514 warn("Can't determine my address of data connection"); 1515 goto bad; 1516 } 1517 data_addr.su_len = len; 1518 if (ftp_listen(data, 1) < 0) 1519 warn("Can't listen to data connection"); 1520 1521 if (sendport) { 1522 char hname[NI_MAXHOST], sname[NI_MAXSERV]; 1523 int af; 1524 struct sockinet tmp; 1525 1526 switch (data_addr.su_family) { 1527 case AF_INET: 1528 if (!epsv4 || epsv4bad) { 1529 result = COMPLETE + 1; 1530 break; 1531 } 1532 /* FALLTHROUGH */ 1533 #ifdef INET6 1534 case AF_INET6: 1535 #endif 1536 af = (data_addr.su_family == AF_INET) ? 1 : 2; 1537 tmp = data_addr; 1538 #ifdef INET6 1539 if (tmp.su_family == AF_INET6) 1540 tmp.si_su.su_sin6.sin6_scope_id = 0; 1541 #endif 1542 if (getnameinfo((struct sockaddr *)&tmp.si_su, 1543 tmp.su_len, hname, sizeof(hname), sname, 1544 sizeof(sname), NI_NUMERICHOST | NI_NUMERICSERV)) { 1545 result = ERROR; 1546 } else { 1547 overbose = verbose; 1548 if (ftp_debug == 0) 1549 verbose = -1; 1550 result = command("EPRT |%d|%s|%s|", af, hname, 1551 sname); 1552 verbose = overbose; 1553 if (verbose > 0 && 1554 (result == COMPLETE || !connected)) 1555 fprintf(ttyout, "%s\n", reply_string); 1556 if (!connected) 1557 return (1); 1558 if (result != COMPLETE) { 1559 epsv4bad = 1; 1560 DPRINTF("disabling epsv4 for this " 1561 "connection\n"); 1562 } 1563 } 1564 break; 1565 default: 1566 result = COMPLETE + 1; 1567 break; 1568 } 1569 if (result == COMPLETE) 1570 goto skip_port; 1571 1572 switch (data_addr.su_family) { 1573 case AF_INET: 1574 a = (char *)&data_addr.si_su.su_sin.sin_addr; 1575 p = (char *)&data_addr.su_port; 1576 result = command("PORT %d,%d,%d,%d,%d,%d", 1577 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 1578 UC(p[0]), UC(p[1])); 1579 break; 1580 #ifdef INET6 1581 case AF_INET6: 1582 a = (char *)&data_addr.si_su.su_sin6.sin6_addr; 1583 p = (char *)&data_addr.su_port; 1584 result = command( 1585 "LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", 1586 6, 16, 1587 UC(a[0]),UC(a[1]),UC(a[2]),UC(a[3]), 1588 UC(a[4]),UC(a[5]),UC(a[6]),UC(a[7]), 1589 UC(a[8]),UC(a[9]),UC(a[10]),UC(a[11]), 1590 UC(a[12]),UC(a[13]),UC(a[14]),UC(a[15]), 1591 2, UC(p[0]), UC(p[1])); 1592 break; 1593 #endif 1594 default: 1595 result = COMPLETE + 1; /* xxx */ 1596 } 1597 if (!connected) 1598 return (1); 1599 skip_port: 1600 1601 if (result == ERROR && sendport == -1) { 1602 sendport = 0; 1603 tmpno = 1; 1604 goto noport; 1605 } 1606 return (result != COMPLETE); 1607 } 1608 if (tmpno) 1609 sendport = 1; 1610 #ifdef IPTOS_THROUGHPUT 1611 if (data_addr.su_family == AF_INET) { 1612 on = IPTOS_THROUGHPUT; 1613 if (setsockopt(data, IPPROTO_IP, IP_TOS, 1614 (void *)&on, sizeof(on)) == -1) 1615 DWARN("setsockopt %s (ignored)", "IPTOS_THROUGHPUT"); 1616 } 1617 #endif 1618 return (0); 1619 bad: 1620 (void)close(data); 1621 data = -1; 1622 if (tmpno) 1623 sendport = 1; 1624 return (1); 1625 } 1626 1627 FILE * 1628 dataconn(const char *lmode) 1629 { 1630 struct sockinet from; 1631 int s, flags, rv, timeout; 1632 struct timeval endtime, now, td; 1633 struct pollfd pfd[1]; 1634 socklen_t fromlen; 1635 1636 if (passivemode) /* passive data connection */ 1637 return (fdopen(data, lmode)); 1638 1639 /* active mode data connection */ 1640 1641 if ((flags = fcntl(data, F_GETFL, 0)) == -1) 1642 goto dataconn_failed; /* get current socket flags */ 1643 if (fcntl(data, F_SETFL, flags | O_NONBLOCK) == -1) 1644 goto dataconn_failed; /* set non-blocking connect */ 1645 1646 /* NOTE: we now must restore socket flags on successful exit */ 1647 1648 /* limit time waiting on listening socket */ 1649 pfd[0].fd = data; 1650 pfd[0].events = POLLIN; 1651 (void)gettimeofday(&endtime, NULL); /* determine end time */ 1652 endtime.tv_sec += (quit_time > 0) ? quit_time: 60; 1653 /* without -q, default to 60s */ 1654 do { 1655 (void)gettimeofday(&now, NULL); 1656 timersub(&endtime, &now, &td); 1657 timeout = td.tv_sec * 1000 + td.tv_usec/1000; 1658 if (timeout < 0) 1659 timeout = 0; 1660 rv = ftp_poll(pfd, 1, timeout); 1661 } while (rv == -1 && errno == EINTR); /* loop until poll ! EINTR */ 1662 if (rv == -1) { 1663 warn("Can't poll waiting before accept"); 1664 goto dataconn_failed; 1665 } 1666 if (rv == 0) { 1667 warnx("Poll timeout waiting before accept"); 1668 goto dataconn_failed; 1669 } 1670 1671 /* (non-blocking) accept the connection */ 1672 fromlen = myctladdr.su_len; 1673 do { 1674 s = accept(data, (struct sockaddr *) &from.si_su, &fromlen); 1675 } while (s == -1 && errno == EINTR); /* loop until accept ! EINTR */ 1676 if (s == -1) { 1677 warn("Can't accept data connection"); 1678 goto dataconn_failed; 1679 } 1680 1681 (void)close(data); 1682 data = s; 1683 if (fcntl(data, F_SETFL, flags) == -1) /* restore socket flags */ 1684 goto dataconn_failed; 1685 1686 #ifdef IPTOS_THROUGHPUT 1687 if (from.su_family == AF_INET) { 1688 int tos = IPTOS_THROUGHPUT; 1689 if (setsockopt(s, IPPROTO_IP, IP_TOS, 1690 (void *)&tos, sizeof(tos)) == -1) { 1691 DWARN("setsockopt %s (ignored)", "IPTOS_THROUGHPUT"); 1692 } 1693 } 1694 #endif 1695 return (fdopen(data, lmode)); 1696 1697 dataconn_failed: 1698 (void)close(data); 1699 data = -1; 1700 return (NULL); 1701 } 1702 1703 void 1704 psabort(int notused) 1705 { 1706 int oerrno = errno; 1707 1708 sigint_raised = 1; 1709 alarmtimer(0); 1710 abrtflag++; 1711 errno = oerrno; 1712 } 1713 1714 void 1715 pswitch(int flag) 1716 { 1717 sigfunc oldintr; 1718 static struct comvars { 1719 int connect; 1720 char name[MAXHOSTNAMELEN]; 1721 struct sockinet mctl; 1722 struct sockinet hctl; 1723 FILE *in; 1724 FILE *out; 1725 int tpe; 1726 int curtpe; 1727 int cpnd; 1728 int sunqe; 1729 int runqe; 1730 int mcse; 1731 int ntflg; 1732 char nti[17]; 1733 char nto[17]; 1734 int mapflg; 1735 char mi[MAXPATHLEN]; 1736 char mo[MAXPATHLEN]; 1737 } proxstruct, tmpstruct; 1738 struct comvars *ip, *op; 1739 1740 abrtflag = 0; 1741 oldintr = xsignal(SIGINT, psabort); 1742 if (flag) { 1743 if (proxy) 1744 return; 1745 ip = &tmpstruct; 1746 op = &proxstruct; 1747 proxy++; 1748 } else { 1749 if (!proxy) 1750 return; 1751 ip = &proxstruct; 1752 op = &tmpstruct; 1753 proxy = 0; 1754 } 1755 ip->connect = connected; 1756 connected = op->connect; 1757 if (hostname) 1758 (void)strlcpy(ip->name, hostname, sizeof(ip->name)); 1759 else 1760 ip->name[0] = '\0'; 1761 hostname = op->name; 1762 ip->hctl = hisctladdr; 1763 hisctladdr = op->hctl; 1764 ip->mctl = myctladdr; 1765 myctladdr = op->mctl; 1766 ip->in = cin; 1767 cin = op->in; 1768 ip->out = cout; 1769 cout = op->out; 1770 ip->tpe = type; 1771 type = op->tpe; 1772 ip->curtpe = curtype; 1773 curtype = op->curtpe; 1774 ip->cpnd = cpend; 1775 cpend = op->cpnd; 1776 ip->sunqe = sunique; 1777 sunique = op->sunqe; 1778 ip->runqe = runique; 1779 runique = op->runqe; 1780 ip->mcse = mcase; 1781 mcase = op->mcse; 1782 ip->ntflg = ntflag; 1783 ntflag = op->ntflg; 1784 (void)strlcpy(ip->nti, ntin, sizeof(ip->nti)); 1785 (void)strlcpy(ntin, op->nti, sizeof(ntin)); 1786 (void)strlcpy(ip->nto, ntout, sizeof(ip->nto)); 1787 (void)strlcpy(ntout, op->nto, sizeof(ntout)); 1788 ip->mapflg = mapflag; 1789 mapflag = op->mapflg; 1790 (void)strlcpy(ip->mi, mapin, sizeof(ip->mi)); 1791 (void)strlcpy(mapin, op->mi, sizeof(mapin)); 1792 (void)strlcpy(ip->mo, mapout, sizeof(ip->mo)); 1793 (void)strlcpy(mapout, op->mo, sizeof(mapout)); 1794 (void)xsignal(SIGINT, oldintr); 1795 if (abrtflag) { 1796 abrtflag = 0; 1797 (*oldintr)(SIGINT); 1798 } 1799 } 1800 1801 void 1802 abortpt(int notused) 1803 { 1804 1805 sigint_raised = 1; 1806 alarmtimer(0); 1807 if (fromatty) 1808 write(fileno(ttyout), "\n", 1); 1809 ptabflg++; 1810 mflag = 0; 1811 abrtflag = 0; 1812 siglongjmp(ptabort, 1); 1813 } 1814 1815 void 1816 proxtrans(const char *cmd, const char *local, const char *remote) 1817 { 1818 sigfunc volatile oldintr; 1819 int prox_type, nfnd; 1820 int volatile secndflag; 1821 char *volatile cmd2; 1822 1823 oldintr = NULL; 1824 secndflag = 0; 1825 if (strcmp(cmd, "RETR")) 1826 cmd2 = "RETR"; 1827 else 1828 cmd2 = runique ? "STOU" : "STOR"; 1829 if ((prox_type = type) == 0) { 1830 if (unix_server && unix_proxy) 1831 prox_type = TYPE_I; 1832 else 1833 prox_type = TYPE_A; 1834 } 1835 if (curtype != prox_type) 1836 changetype(prox_type, 1); 1837 if (command("PASV") != COMPLETE) { 1838 fputs("proxy server does not support third party transfers.\n", 1839 ttyout); 1840 return; 1841 } 1842 pswitch(0); 1843 if (!connected) { 1844 fputs("No primary connection.\n", ttyout); 1845 pswitch(1); 1846 code = -1; 1847 return; 1848 } 1849 if (curtype != prox_type) 1850 changetype(prox_type, 1); 1851 if (command("PORT %s", pasv) != COMPLETE) { 1852 pswitch(1); 1853 return; 1854 } 1855 if (sigsetjmp(ptabort, 1)) 1856 goto abort; 1857 oldintr = xsignal(SIGINT, abortpt); 1858 if ((restart_point && 1859 (command("REST " LLF, (LLT) restart_point) != CONTINUE)) 1860 || (command("%s %s", cmd, remote) != PRELIM)) { 1861 (void)xsignal(SIGINT, oldintr); 1862 pswitch(1); 1863 return; 1864 } 1865 sleep(2); 1866 pswitch(1); 1867 secndflag++; 1868 if ((restart_point && 1869 (command("REST " LLF, (LLT) restart_point) != CONTINUE)) 1870 || (command("%s %s", cmd2, local) != PRELIM)) 1871 goto abort; 1872 ptflag++; 1873 (void)getreply(0); 1874 pswitch(0); 1875 (void)getreply(0); 1876 (void)xsignal(SIGINT, oldintr); 1877 pswitch(1); 1878 ptflag = 0; 1879 fprintf(ttyout, "local: %s remote: %s\n", local, remote); 1880 return; 1881 abort: 1882 if (sigsetjmp(xferabort, 1)) { 1883 (void)xsignal(SIGINT, oldintr); 1884 return; 1885 } 1886 (void)xsignal(SIGINT, abort_squared); 1887 ptflag = 0; 1888 if (strcmp(cmd, "RETR") && !proxy) 1889 pswitch(1); 1890 else if (!strcmp(cmd, "RETR") && proxy) 1891 pswitch(0); 1892 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ 1893 if (command("%s %s", cmd2, local) != PRELIM) { 1894 pswitch(0); 1895 if (cpend) 1896 abort_remote(NULL); 1897 } 1898 pswitch(1); 1899 if (ptabflg) 1900 code = -1; 1901 (void)xsignal(SIGINT, oldintr); 1902 return; 1903 } 1904 if (cpend) 1905 abort_remote(NULL); 1906 pswitch(!proxy); 1907 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */ 1908 if (command("%s %s", cmd2, local) != PRELIM) { 1909 pswitch(0); 1910 if (cpend) 1911 abort_remote(NULL); 1912 pswitch(1); 1913 if (ptabflg) 1914 code = -1; 1915 (void)xsignal(SIGINT, oldintr); 1916 return; 1917 } 1918 } 1919 if (cpend) 1920 abort_remote(NULL); 1921 pswitch(!proxy); 1922 if (cpend) { 1923 if ((nfnd = empty(cin, NULL, 10)) <= 0) { 1924 if (nfnd < 0) 1925 warn("Error aborting proxy command"); 1926 if (ptabflg) 1927 code = -1; 1928 lostpeer(0); 1929 } 1930 (void)getreply(0); 1931 (void)getreply(0); 1932 } 1933 if (proxy) 1934 pswitch(0); 1935 pswitch(1); 1936 if (ptabflg) 1937 code = -1; 1938 (void)xsignal(SIGINT, oldintr); 1939 } 1940 1941 void 1942 reset(int argc, char *argv[]) 1943 { 1944 int nfnd = 1; 1945 1946 if (argc == 0 && argv != NULL) { 1947 UPRINTF("usage: %s\n", argv[0]); 1948 code = -1; 1949 return; 1950 } 1951 while (nfnd > 0) { 1952 if ((nfnd = empty(cin, NULL, 0)) < 0) { 1953 warn("Error resetting connection"); 1954 code = -1; 1955 lostpeer(0); 1956 } else if (nfnd) 1957 (void)getreply(0); 1958 } 1959 } 1960 1961 char * 1962 gunique(const char *local) 1963 { 1964 static char new[MAXPATHLEN]; 1965 char *cp = strrchr(local, '/'); 1966 int d, count=0, len; 1967 char ext = '1'; 1968 1969 if (cp) 1970 *cp = '\0'; 1971 d = access(cp == local ? "/" : cp ? local : ".", W_OK); 1972 if (cp) 1973 *cp = '/'; 1974 if (d < 0) { 1975 warn("Can't access `%s'", local); 1976 return (NULL); 1977 } 1978 len = strlcpy(new, local, sizeof(new)); 1979 cp = &new[len]; 1980 *cp++ = '.'; 1981 while (!d) { 1982 if (++count == 100) { 1983 fputs("runique: can't find unique file name.\n", 1984 ttyout); 1985 return (NULL); 1986 } 1987 *cp++ = ext; 1988 *cp = '\0'; 1989 if (ext == '9') 1990 ext = '0'; 1991 else 1992 ext++; 1993 if ((d = access(new, F_OK)) < 0) 1994 break; 1995 if (ext != '0') 1996 cp--; 1997 else if (*(cp - 2) == '.') 1998 *(cp - 1) = '1'; 1999 else { 2000 *(cp - 2) = *(cp - 2) + 1; 2001 cp--; 2002 } 2003 } 2004 return (new); 2005 } 2006 2007 /* 2008 * abort_squared -- 2009 * aborts abort_remote(). lostpeer() is called because if the user is 2010 * too impatient to wait or there's another problem then ftp really 2011 * needs to get back to a known state. 2012 */ 2013 void 2014 abort_squared(int dummy) 2015 { 2016 char msgbuf[100]; 2017 size_t len; 2018 2019 sigint_raised = 1; 2020 alarmtimer(0); 2021 len = strlcpy(msgbuf, "\nremote abort aborted; closing connection.\n", 2022 sizeof(msgbuf)); 2023 write(fileno(ttyout), msgbuf, len); 2024 lostpeer(0); 2025 siglongjmp(xferabort, 1); 2026 } 2027 2028 void 2029 abort_remote(FILE *din) 2030 { 2031 char buf[BUFSIZ]; 2032 int nfnd; 2033 2034 if (cout == NULL) { 2035 warnx("Lost control connection for abort"); 2036 if (ptabflg) 2037 code = -1; 2038 lostpeer(0); 2039 return; 2040 } 2041 /* 2042 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark 2043 * after urgent byte rather than before as is protocol now 2044 */ 2045 buf[0] = IAC; 2046 buf[1] = IP; 2047 buf[2] = IAC; 2048 if (send(fileno(cout), buf, 3, MSG_OOB) != 3) 2049 warn("Can't send abort message"); 2050 fprintf(cout, "%cABOR\r\n", DM); 2051 (void)fflush(cout); 2052 if ((nfnd = empty(cin, din, 10)) <= 0) { 2053 if (nfnd < 0) 2054 warn("Can't send abort message"); 2055 if (ptabflg) 2056 code = -1; 2057 lostpeer(0); 2058 } 2059 if (din && (nfnd & 2)) { 2060 while (read(fileno(din), buf, BUFSIZ) > 0) 2061 continue; 2062 } 2063 if (getreply(0) == ERROR && code == 552) { 2064 /* 552 needed for nic style abort */ 2065 (void)getreply(0); 2066 } 2067 (void)getreply(0); 2068 } 2069 2070 /* 2071 * Ensure that ai->ai_addr is NOT an IPv4 mapped address. 2072 * IPv4 mapped address complicates too many things in FTP 2073 * protocol handling, as FTP protocol is defined differently 2074 * between IPv4 and IPv6. 2075 * 2076 * This may not be the best way to handle this situation, 2077 * since the semantics of IPv4 mapped address is defined in 2078 * the kernel. There are configurations where we should use 2079 * IPv4 mapped address as native IPv6 address, not as 2080 * "an IPv6 address that embeds IPv4 address" (namely, SIIT). 2081 * 2082 * More complete solution would be to have an additional 2083 * getsockopt to grab "real" peername/sockname. "real" 2084 * peername/sockname will be AF_INET if IPv4 mapped address 2085 * is used to embed IPv4 address, and will be AF_INET6 if 2086 * we use it as native. What a mess! 2087 */ 2088 void 2089 ai_unmapped(struct addrinfo *ai) 2090 { 2091 #ifdef INET6 2092 struct sockaddr_in6 *sin6; 2093 struct sockaddr_in sin; 2094 socklen_t len; 2095 2096 if (ai->ai_family != AF_INET6) 2097 return; 2098 if (ai->ai_addrlen != sizeof(struct sockaddr_in6) || 2099 sizeof(sin) > ai->ai_addrlen) 2100 return; 2101 sin6 = (struct sockaddr_in6 *)ai->ai_addr; 2102 if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) 2103 return; 2104 2105 memset(&sin, 0, sizeof(sin)); 2106 sin.sin_family = AF_INET; 2107 len = sizeof(struct sockaddr_in); 2108 memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12], 2109 sizeof(sin.sin_addr)); 2110 sin.sin_port = sin6->sin6_port; 2111 2112 ai->ai_family = AF_INET; 2113 #if defined(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN) 2114 sin.sin_len = len; 2115 #endif 2116 memcpy(ai->ai_addr, &sin, len); 2117 ai->ai_addrlen = len; 2118 #endif 2119 } 2120 2121 #ifdef NO_USAGE 2122 void 2123 xusage(void) 2124 { 2125 fputs("Usage error\n", ttyout); 2126 } 2127 #endif 2128