1 /* 2 * Copyright (c) 1985, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)ftp.c 5.33 (Berkeley) 05/22/90"; 20 #endif /* not lint */ 21 22 #include <sys/param.h> 23 #include <sys/stat.h> 24 #include <sys/ioctl.h> 25 #include <sys/socket.h> 26 #include <sys/time.h> 27 #include <sys/file.h> 28 29 #include <netinet/in.h> 30 #include <arpa/ftp.h> 31 #include <arpa/telnet.h> 32 33 #include <stdio.h> 34 #include <signal.h> 35 #include <errno.h> 36 #include <netdb.h> 37 #include <fcntl.h> 38 #include <pwd.h> 39 #include <varargs.h> 40 41 #include "ftp_var.h" 42 43 struct sockaddr_in hisctladdr; 44 struct sockaddr_in data_addr; 45 int data = -1; 46 int abrtflag = 0; 47 int ptflag = 0; 48 struct sockaddr_in myctladdr; 49 uid_t getuid(); 50 sig_t lostpeer(); 51 off_t restart_point = 0; 52 53 extern char *strerror(); 54 extern int connected, errno; 55 56 FILE *cin, *cout; 57 FILE *dataconn(); 58 59 char * 60 hookup(host, port) 61 char *host; 62 int port; 63 { 64 register struct hostent *hp = 0; 65 int s,len; 66 static char hostnamebuf[80]; 67 68 bzero((char *)&hisctladdr, sizeof (hisctladdr)); 69 hisctladdr.sin_addr.s_addr = inet_addr(host); 70 if (hisctladdr.sin_addr.s_addr != -1) { 71 hisctladdr.sin_family = AF_INET; 72 (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf)); 73 } else { 74 hp = gethostbyname(host); 75 if (hp == NULL) { 76 fprintf(stderr, "ftp: %s: ", host); 77 herror((char *)NULL); 78 code = -1; 79 return((char *) 0); 80 } 81 hisctladdr.sin_family = hp->h_addrtype; 82 bcopy(hp->h_addr_list[0], 83 (caddr_t)&hisctladdr.sin_addr, hp->h_length); 84 (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf)); 85 } 86 hostname = hostnamebuf; 87 s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); 88 if (s < 0) { 89 perror("ftp: socket"); 90 code = -1; 91 return (0); 92 } 93 hisctladdr.sin_port = port; 94 while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) { 95 if (hp && hp->h_addr_list[1]) { 96 int oerrno = errno; 97 extern char *inet_ntoa(); 98 99 fprintf(stderr, "ftp: connect to address %s: ", 100 inet_ntoa(hisctladdr.sin_addr)); 101 errno = oerrno; 102 perror((char *) 0); 103 hp->h_addr_list++; 104 bcopy(hp->h_addr_list[0], 105 (caddr_t)&hisctladdr.sin_addr, hp->h_length); 106 fprintf(stdout, "Trying %s...\n", 107 inet_ntoa(hisctladdr.sin_addr)); 108 (void) close(s); 109 s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); 110 if (s < 0) { 111 perror("ftp: socket"); 112 code = -1; 113 return (0); 114 } 115 continue; 116 } 117 perror("ftp: connect"); 118 code = -1; 119 goto bad; 120 } 121 len = sizeof (myctladdr); 122 if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) { 123 perror("ftp: getsockname"); 124 code = -1; 125 goto bad; 126 } 127 cin = fdopen(s, "r"); 128 cout = fdopen(s, "w"); 129 if (cin == NULL || cout == NULL) { 130 fprintf(stderr, "ftp: fdopen failed.\n"); 131 if (cin) 132 (void) fclose(cin); 133 if (cout) 134 (void) fclose(cout); 135 code = -1; 136 goto bad; 137 } 138 if (verbose) 139 printf("Connected to %s.\n", hostname); 140 if (getreply(0) > 2) { /* read startup message from server */ 141 if (cin) 142 (void) fclose(cin); 143 if (cout) 144 (void) fclose(cout); 145 code = -1; 146 goto bad; 147 } 148 #ifdef SO_OOBINLINE 149 { 150 int on = 1; 151 152 if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) 153 < 0 && debug) { 154 perror("ftp: setsockopt"); 155 } 156 } 157 #endif /* SO_OOBINLINE */ 158 159 return (hostname); 160 bad: 161 (void) close(s); 162 return ((char *)0); 163 } 164 165 login(host) 166 char *host; 167 { 168 char tmp[80]; 169 char *user, *pass, *acct, *getlogin(), *getpass(); 170 int n, aflag = 0; 171 172 user = pass = acct = 0; 173 if (ruserpass(host, &user, &pass, &acct) < 0) { 174 code = -1; 175 return(0); 176 } 177 while (user == NULL) { 178 char *myname = getlogin(); 179 180 if (myname == NULL) { 181 struct passwd *pp = getpwuid(getuid()); 182 183 if (pp != NULL) 184 myname = pp->pw_name; 185 } 186 if (myname) 187 printf("Name (%s:%s): ", host, myname); 188 else 189 printf("Name (%s): ", host); 190 (void) fgets(tmp, sizeof(tmp) - 1, stdin); 191 tmp[strlen(tmp) - 1] = '\0'; 192 if (*tmp == '\0') 193 user = myname; 194 else 195 user = tmp; 196 } 197 n = command("USER %s", user); 198 if (n == CONTINUE) { 199 if (pass == NULL) 200 pass = getpass("Password:"); 201 n = command("PASS %s", pass); 202 } 203 if (n == CONTINUE) { 204 aflag++; 205 acct = getpass("Account:"); 206 n = command("ACCT %s", acct); 207 } 208 if (n != COMPLETE) { 209 fprintf(stderr, "Login failed.\n"); 210 return (0); 211 } 212 if (!aflag && acct != NULL) 213 (void) command("ACCT %s", acct); 214 if (proxy) 215 return(1); 216 for (n = 0; n < macnum; ++n) { 217 if (!strcmp("init", macros[n].mac_name)) { 218 (void) strcpy(line, "$init"); 219 makeargv(); 220 domacro(margc, margv); 221 break; 222 } 223 } 224 return (1); 225 } 226 227 void 228 cmdabort() 229 { 230 extern jmp_buf ptabort; 231 232 printf("\n"); 233 (void) fflush(stdout); 234 abrtflag++; 235 if (ptflag) 236 longjmp(ptabort,1); 237 } 238 239 /*VARARGS*/ 240 command(va_alist) 241 va_dcl 242 { 243 va_list ap; 244 char *fmt; 245 int r; 246 sig_t oldintr; 247 void cmdabort(); 248 249 abrtflag = 0; 250 if (debug) { 251 printf("---> "); 252 va_start(ap); 253 fmt = va_arg(ap, char *); 254 if (strncmp("PASS ", fmt, 5) == 0) 255 printf("PASS XXXX"); 256 else 257 vfprintf(stdout, fmt, ap); 258 va_end(ap); 259 printf("\n"); 260 (void) fflush(stdout); 261 } 262 if (cout == NULL) { 263 perror ("No control connection for command"); 264 code = -1; 265 return (0); 266 } 267 oldintr = signal(SIGINT, cmdabort); 268 va_start(ap); 269 fmt = va_arg(ap, char *); 270 vfprintf(cout, fmt, ap); 271 va_end(ap); 272 fprintf(cout, "\r\n"); 273 (void) fflush(cout); 274 cpend = 1; 275 r = getreply(!strcmp(fmt, "QUIT")); 276 if (abrtflag && oldintr != SIG_IGN) 277 (*oldintr)(); 278 (void) signal(SIGINT, oldintr); 279 return(r); 280 } 281 282 char reply_string[BUFSIZ]; /* last line of previous reply */ 283 284 #include <ctype.h> 285 286 getreply(expecteof) 287 int expecteof; 288 { 289 register int c, n; 290 register int dig; 291 register char *cp; 292 int originalcode = 0, continuation = 0; 293 sig_t oldintr; 294 int pflag = 0; 295 char *pt = pasv; 296 void cmdabort(); 297 298 oldintr = signal(SIGINT, cmdabort); 299 for (;;) { 300 dig = n = code = 0; 301 cp = reply_string; 302 while ((c = getc(cin)) != '\n') { 303 if (c == IAC) { /* handle telnet commands */ 304 switch (c = getc(cin)) { 305 case WILL: 306 case WONT: 307 c = getc(cin); 308 fprintf(cout, "%c%c%c", IAC, DONT, c); 309 (void) fflush(cout); 310 break; 311 case DO: 312 case DONT: 313 c = getc(cin); 314 fprintf(cout, "%c%c%c", IAC, WONT, c); 315 (void) fflush(cout); 316 break; 317 default: 318 break; 319 } 320 continue; 321 } 322 dig++; 323 if (c == EOF) { 324 if (expecteof) { 325 (void) signal(SIGINT,oldintr); 326 code = 221; 327 return (0); 328 } 329 lostpeer(); 330 if (verbose) { 331 printf("421 Service not available, remote server has closed connection\n"); 332 (void) fflush(stdout); 333 } 334 code = 421; 335 return(4); 336 } 337 if (c != '\r' && (verbose > 0 || 338 (verbose > -1 && n == '5' && dig > 4))) { 339 if (proxflag && 340 (dig == 1 || dig == 5 && verbose == 0)) 341 printf("%s:",hostname); 342 (void) putchar(c); 343 } 344 if (dig < 4 && isdigit(c)) 345 code = code * 10 + (c - '0'); 346 if (!pflag && code == 227) 347 pflag = 1; 348 if (dig > 4 && pflag == 1 && isdigit(c)) 349 pflag = 2; 350 if (pflag == 2) { 351 if (c != '\r' && c != ')') 352 *pt++ = c; 353 else { 354 *pt = '\0'; 355 pflag = 3; 356 } 357 } 358 if (dig == 4 && c == '-') { 359 if (continuation) 360 code = 0; 361 continuation++; 362 } 363 if (n == 0) 364 n = c; 365 if (cp < &reply_string[sizeof(reply_string) - 1]) 366 *cp++ = c; 367 } 368 if (verbose > 0 || verbose > -1 && n == '5') { 369 (void) putchar(c); 370 (void) fflush (stdout); 371 } 372 if (continuation && code != originalcode) { 373 if (originalcode == 0) 374 originalcode = code; 375 continue; 376 } 377 *cp = '\0'; 378 if (n != '1') 379 cpend = 0; 380 (void) signal(SIGINT,oldintr); 381 if (code == 421 || originalcode == 421) 382 lostpeer(); 383 if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN) 384 (*oldintr)(); 385 return (n - '0'); 386 } 387 } 388 389 empty(mask, sec) 390 struct fd_set *mask; 391 int sec; 392 { 393 struct timeval t; 394 395 t.tv_sec = (long) sec; 396 t.tv_usec = 0; 397 return(select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t)); 398 } 399 400 jmp_buf sendabort; 401 402 void 403 abortsend() 404 { 405 406 mflag = 0; 407 abrtflag = 0; 408 printf("\nsend aborted\nwaiting for remote to finish abort\n"); 409 (void) fflush(stdout); 410 longjmp(sendabort, 1); 411 } 412 413 #define HASHBYTES 1024 414 415 sendrequest(cmd, local, remote, printnames) 416 char *cmd, *local, *remote; 417 int printnames; 418 { 419 struct stat st; 420 struct timeval start, stop; 421 register int c, d; 422 FILE *fin, *dout = 0, *popen(); 423 int (*closefunc)(), pclose(), fclose(); 424 sig_t oldintr, oldintp; 425 long bytes = 0, hashbytes = HASHBYTES; 426 char *lmode, buf[BUFSIZ], *bufp; 427 void abortsend(); 428 429 if (verbose && printnames) { 430 if (local && *local != '-') 431 printf("local: %s ", local); 432 if (remote) 433 printf("remote: %s\n", remote); 434 } 435 if (proxy) { 436 proxtrans(cmd, local, remote); 437 return; 438 } 439 if (curtype != type) 440 changetype(type, 0); 441 closefunc = NULL; 442 oldintr = NULL; 443 oldintp = NULL; 444 lmode = "w"; 445 if (setjmp(sendabort)) { 446 while (cpend) { 447 (void) getreply(0); 448 } 449 if (data >= 0) { 450 (void) close(data); 451 data = -1; 452 } 453 if (oldintr) 454 (void) signal(SIGINT,oldintr); 455 if (oldintp) 456 (void) signal(SIGPIPE,oldintp); 457 code = -1; 458 return; 459 } 460 oldintr = signal(SIGINT, abortsend); 461 if (strcmp(local, "-") == 0) 462 fin = stdin; 463 else if (*local == '|') { 464 oldintp = signal(SIGPIPE,SIG_IGN); 465 fin = popen(local + 1, "r"); 466 if (fin == NULL) { 467 perror(local + 1); 468 (void) signal(SIGINT, oldintr); 469 (void) signal(SIGPIPE, oldintp); 470 code = -1; 471 return; 472 } 473 closefunc = pclose; 474 } else { 475 fin = fopen(local, "r"); 476 if (fin == NULL) { 477 fprintf(stderr, "local: %s: %s\n", local, 478 strerror(errno)); 479 (void) signal(SIGINT, oldintr); 480 code = -1; 481 return; 482 } 483 closefunc = fclose; 484 if (fstat(fileno(fin), &st) < 0 || 485 (st.st_mode&S_IFMT) != S_IFREG) { 486 fprintf(stdout, "%s: not a plain file.\n", local); 487 (void) signal(SIGINT, oldintr); 488 fclose(fin); 489 code = -1; 490 return; 491 } 492 } 493 if (initconn()) { 494 (void) signal(SIGINT, oldintr); 495 if (oldintp) 496 (void) signal(SIGPIPE, oldintp); 497 code = -1; 498 if (closefunc != NULL) 499 (*closefunc)(fin); 500 return; 501 } 502 if (setjmp(sendabort)) 503 goto abort; 504 505 if (restart_point && 506 (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) { 507 if (fseek(fin, (long) restart_point, 0) < 0) { 508 fprintf(stderr, "local: %s: %s\n", local, 509 strerror(errno)); 510 restart_point = 0; 511 if (closefunc != NULL) 512 (*closefunc)(fin); 513 return; 514 } 515 if (command("REST %ld", (long) restart_point) 516 != CONTINUE) { 517 restart_point = 0; 518 if (closefunc != NULL) 519 (*closefunc)(fin); 520 return; 521 } 522 restart_point = 0; 523 lmode = "r+w"; 524 } 525 if (remote) { 526 if (command("%s %s", cmd, remote) != PRELIM) { 527 (void) signal(SIGINT, oldintr); 528 if (oldintp) 529 (void) signal(SIGPIPE, oldintp); 530 if (closefunc != NULL) 531 (*closefunc)(fin); 532 return; 533 } 534 } else 535 if (command("%s", cmd) != PRELIM) { 536 (void) signal(SIGINT, oldintr); 537 if (oldintp) 538 (void) signal(SIGPIPE, oldintp); 539 if (closefunc != NULL) 540 (*closefunc)(fin); 541 return; 542 } 543 dout = dataconn(lmode); 544 if (dout == NULL) 545 goto abort; 546 (void) gettimeofday(&start, (struct timezone *)0); 547 oldintp = signal(SIGPIPE, SIG_IGN); 548 switch (curtype) { 549 550 case TYPE_I: 551 case TYPE_L: 552 errno = d = 0; 553 while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) { 554 bytes += c; 555 for (bufp = buf; c > 0; c -= d, bufp += d) 556 if ((d = write(fileno(dout), bufp, c)) <= 0) 557 break; 558 if (hash) { 559 while (bytes >= hashbytes) { 560 (void) putchar('#'); 561 hashbytes += HASHBYTES; 562 } 563 (void) fflush(stdout); 564 } 565 } 566 if (hash && bytes > 0) { 567 if (bytes < HASHBYTES) 568 (void) putchar('#'); 569 (void) putchar('\n'); 570 (void) fflush(stdout); 571 } 572 if (c < 0) 573 fprintf(stderr, "local: %s: %s\n", local, 574 strerror(errno)); 575 if (d <= 0) { 576 if (d == 0) 577 fprintf(stderr, "netout: write returned 0?\n"); 578 else if (errno != EPIPE) 579 perror("netout"); 580 bytes = -1; 581 } 582 break; 583 584 case TYPE_A: 585 while ((c = getc(fin)) != EOF) { 586 if (c == '\n') { 587 while (hash && (bytes >= hashbytes)) { 588 (void) putchar('#'); 589 (void) fflush(stdout); 590 hashbytes += HASHBYTES; 591 } 592 if (ferror(dout)) 593 break; 594 (void) putc('\r', dout); 595 bytes++; 596 } 597 (void) putc(c, dout); 598 bytes++; 599 /* if (c == '\r') { */ 600 /* (void) putc('\0', dout); /* this violates rfc */ 601 /* bytes++; */ 602 /* } */ 603 } 604 if (hash) { 605 if (bytes < hashbytes) 606 (void) putchar('#'); 607 (void) putchar('\n'); 608 (void) fflush(stdout); 609 } 610 if (ferror(fin)) 611 fprintf(stderr, "local: %s: %s\n", local, 612 strerror(errno)); 613 if (ferror(dout)) { 614 if (errno != EPIPE) 615 perror("netout"); 616 bytes = -1; 617 } 618 break; 619 } 620 (void) gettimeofday(&stop, (struct timezone *)0); 621 if (closefunc != NULL) 622 (*closefunc)(fin); 623 (void) fclose(dout); 624 (void) getreply(0); 625 (void) signal(SIGINT, oldintr); 626 if (oldintp) 627 (void) signal(SIGPIPE, oldintp); 628 if (bytes > 0) 629 ptransfer("sent", bytes, &start, &stop); 630 return; 631 abort: 632 (void) gettimeofday(&stop, (struct timezone *)0); 633 (void) signal(SIGINT, oldintr); 634 if (oldintp) 635 (void) signal(SIGPIPE, oldintp); 636 if (!cpend) { 637 code = -1; 638 return; 639 } 640 if (data >= 0) { 641 (void) close(data); 642 data = -1; 643 } 644 if (dout) 645 (void) fclose(dout); 646 (void) getreply(0); 647 code = -1; 648 if (closefunc != NULL && fin != NULL) 649 (*closefunc)(fin); 650 if (bytes > 0) 651 ptransfer("sent", bytes, &start, &stop); 652 } 653 654 jmp_buf recvabort; 655 656 void 657 abortrecv() 658 { 659 660 mflag = 0; 661 abrtflag = 0; 662 printf("\nreceive aborted\nwaiting for remote to finish abort\n"); 663 (void) fflush(stdout); 664 longjmp(recvabort, 1); 665 } 666 667 recvrequest(cmd, local, remote, lmode, printnames) 668 char *cmd, *local, *remote, *lmode; 669 { 670 FILE *fout, *din = 0, *popen(); 671 int (*closefunc)(), pclose(), fclose(); 672 sig_t oldintr, oldintp; 673 int is_retr, tcrflag, bare_lfs = 0; 674 char *gunique(); 675 static int bufsize; 676 static char *buf; 677 long bytes = 0, hashbytes = HASHBYTES; 678 register int c, d; 679 struct timeval start, stop; 680 struct stat st; 681 off_t lseek(); 682 void abortrecv(); 683 char *malloc(); 684 685 is_retr = strcmp(cmd, "RETR") == 0; 686 if (is_retr && verbose && printnames) { 687 if (local && *local != '-') 688 printf("local: %s ", local); 689 if (remote) 690 printf("remote: %s\n", remote); 691 } 692 if (proxy && is_retr) { 693 proxtrans(cmd, local, remote); 694 return; 695 } 696 closefunc = NULL; 697 oldintr = NULL; 698 oldintp = NULL; 699 tcrflag = !crflag && is_retr; 700 if (setjmp(recvabort)) { 701 while (cpend) { 702 (void) getreply(0); 703 } 704 if (data >= 0) { 705 (void) close(data); 706 data = -1; 707 } 708 if (oldintr) 709 (void) signal(SIGINT, oldintr); 710 code = -1; 711 return; 712 } 713 oldintr = signal(SIGINT, abortrecv); 714 if (strcmp(local, "-") && *local != '|') { 715 if (access(local, 2) < 0) { 716 char *dir = rindex(local, '/'); 717 718 if (errno != ENOENT && errno != EACCES) { 719 fprintf(stderr, "local: %s: %s\n", local, 720 strerror(errno)); 721 (void) signal(SIGINT, oldintr); 722 code = -1; 723 return; 724 } 725 if (dir != NULL) 726 *dir = 0; 727 d = access(dir ? local : ".", 2); 728 if (dir != NULL) 729 *dir = '/'; 730 if (d < 0) { 731 fprintf(stderr, "local: %s: %s\n", local, 732 strerror(errno)); 733 (void) signal(SIGINT, oldintr); 734 code = -1; 735 return; 736 } 737 if (!runique && errno == EACCES && 738 chmod(local, 0600) < 0) { 739 fprintf(stderr, "local: %s: %s\n", local, 740 strerror(errno)); 741 (void) signal(SIGINT, oldintr); 742 (void) signal(SIGINT, oldintr); 743 code = -1; 744 return; 745 } 746 if (runique && errno == EACCES && 747 (local = gunique(local)) == NULL) { 748 (void) signal(SIGINT, oldintr); 749 code = -1; 750 return; 751 } 752 } 753 else if (runique && (local = gunique(local)) == NULL) { 754 (void) signal(SIGINT, oldintr); 755 code = -1; 756 return; 757 } 758 } 759 if (!is_retr) { 760 if (curtype != TYPE_A) 761 changetype(TYPE_A, 0); 762 } else if (curtype != type) 763 changetype(type, 0); 764 if (initconn()) { 765 (void) signal(SIGINT, oldintr); 766 code = -1; 767 return; 768 } 769 if (setjmp(recvabort)) 770 goto abort; 771 if (is_retr && restart_point && 772 command("REST %ld", (long) restart_point) != CONTINUE) 773 return; 774 if (remote) { 775 if (command("%s %s", cmd, remote) != PRELIM) { 776 (void) signal(SIGINT, oldintr); 777 return; 778 } 779 } else { 780 if (command("%s", cmd) != PRELIM) { 781 (void) signal(SIGINT, oldintr); 782 return; 783 } 784 } 785 din = dataconn("r"); 786 if (din == NULL) 787 goto abort; 788 if (strcmp(local, "-") == 0) 789 fout = stdout; 790 else if (*local == '|') { 791 oldintp = signal(SIGPIPE, SIG_IGN); 792 fout = popen(local + 1, "w"); 793 if (fout == NULL) { 794 perror(local+1); 795 goto abort; 796 } 797 closefunc = pclose; 798 } else { 799 fout = fopen(local, lmode); 800 if (fout == NULL) { 801 fprintf(stderr, "local: %s: %s\n", local, 802 strerror(errno)); 803 goto abort; 804 } 805 closefunc = fclose; 806 } 807 if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0) 808 st.st_blksize = BUFSIZ; 809 if (st.st_blksize > bufsize) { 810 if (buf) 811 (void) free(buf); 812 buf = malloc((unsigned)st.st_blksize); 813 if (buf == NULL) { 814 perror("malloc"); 815 bufsize = 0; 816 goto abort; 817 } 818 bufsize = st.st_blksize; 819 } 820 (void) gettimeofday(&start, (struct timezone *)0); 821 switch (curtype) { 822 823 case TYPE_I: 824 case TYPE_L: 825 if (restart_point && 826 lseek(fileno(fout), (long) restart_point, L_SET) < 0) { 827 fprintf(stderr, "local: %s: %s\n", local, 828 strerror(errno)); 829 if (closefunc != NULL) 830 (*closefunc)(fout); 831 return; 832 } 833 errno = d = 0; 834 while ((c = read(fileno(din), buf, bufsize)) > 0) { 835 if ((d = write(fileno(fout), buf, c)) != c) 836 break; 837 bytes += c; 838 if (hash) { 839 while (bytes >= hashbytes) { 840 (void) putchar('#'); 841 hashbytes += HASHBYTES; 842 } 843 (void) fflush(stdout); 844 } 845 } 846 if (hash && bytes > 0) { 847 if (bytes < HASHBYTES) 848 (void) putchar('#'); 849 (void) putchar('\n'); 850 (void) fflush(stdout); 851 } 852 if (c < 0) { 853 if (errno != EPIPE) 854 perror("netin"); 855 bytes = -1; 856 } 857 if (d < c) { 858 if (d < 0) 859 fprintf(stderr, "local: %s: %s\n", local, 860 strerror(errno)); 861 else 862 fprintf(stderr, "%s: short write\n", local); 863 } 864 break; 865 866 case TYPE_A: 867 if (restart_point) { 868 register int i, n, ch; 869 870 if (fseek(fout, 0L, L_SET) < 0) 871 goto done; 872 n = restart_point; 873 for (i = 0; i++ < n;) { 874 if ((ch = getc(fout)) == EOF) 875 goto done; 876 if (ch == '\n') 877 i++; 878 } 879 if (fseek(fout, 0L, L_INCR) < 0) { 880 done: 881 fprintf(stderr, "local: %s: %s\n", local, 882 strerror(errno)); 883 if (closefunc != NULL) 884 (*closefunc)(fout); 885 return; 886 } 887 } 888 while ((c = getc(din)) != EOF) { 889 if (c == '\n') 890 bare_lfs++; 891 while (c == '\r') { 892 while (hash && (bytes >= hashbytes)) { 893 (void) putchar('#'); 894 (void) fflush(stdout); 895 hashbytes += HASHBYTES; 896 } 897 bytes++; 898 if ((c = getc(din)) != '\n' || tcrflag) { 899 if (ferror(fout)) 900 goto break2; 901 (void) putc('\r', fout); 902 if (c == '\0') { 903 bytes++; 904 goto contin2; 905 } 906 if (c == EOF) 907 goto contin2; 908 } 909 } 910 (void) putc(c, fout); 911 bytes++; 912 contin2: ; 913 } 914 break2: 915 if (bare_lfs) { 916 printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs); 917 printf("File may not have transferred correctly.\n"); 918 } 919 if (hash) { 920 if (bytes < hashbytes) 921 (void) putchar('#'); 922 (void) putchar('\n'); 923 (void) fflush(stdout); 924 } 925 if (ferror(din)) { 926 if (errno != EPIPE) 927 perror("netin"); 928 bytes = -1; 929 } 930 if (ferror(fout)) 931 fprintf(stderr, "local: %s: %s\n", local, 932 strerror(errno)); 933 break; 934 } 935 if (closefunc != NULL) 936 (*closefunc)(fout); 937 (void) signal(SIGINT, oldintr); 938 if (oldintp) 939 (void) signal(SIGPIPE, oldintp); 940 (void) gettimeofday(&stop, (struct timezone *)0); 941 (void) fclose(din); 942 (void) getreply(0); 943 if (bytes > 0 && is_retr) 944 ptransfer("received", bytes, &start, &stop); 945 return; 946 abort: 947 948 /* abort using RFC959 recommended IP,SYNC sequence */ 949 950 (void) gettimeofday(&stop, (struct timezone *)0); 951 if (oldintp) 952 (void) signal(SIGPIPE, oldintr); 953 (void) signal(SIGINT, SIG_IGN); 954 if (!cpend) { 955 code = -1; 956 (void) signal(SIGINT, oldintr); 957 return; 958 } 959 960 abort_remote(din); 961 code = -1; 962 if (data >= 0) { 963 (void) close(data); 964 data = -1; 965 } 966 if (closefunc != NULL && fout != NULL) 967 (*closefunc)(fout); 968 if (din) 969 (void) fclose(din); 970 if (bytes > 0) 971 ptransfer("received", bytes, &start, &stop); 972 (void) signal(SIGINT, oldintr); 973 } 974 975 /* 976 * Need to start a listen on the data channel before we send the command, 977 * otherwise the server's connect may fail. 978 */ 979 initconn() 980 { 981 register char *p, *a; 982 int result, len, tmpno = 0; 983 int on = 1; 984 985 noport: 986 data_addr = myctladdr; 987 if (sendport) 988 data_addr.sin_port = 0; /* let system pick one */ 989 if (data != -1) 990 (void) close(data); 991 data = socket(AF_INET, SOCK_STREAM, 0); 992 if (data < 0) { 993 perror("ftp: socket"); 994 if (tmpno) 995 sendport = 1; 996 return (1); 997 } 998 if (!sendport) 999 if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) { 1000 perror("ftp: setsockopt (reuse address)"); 1001 goto bad; 1002 } 1003 if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) { 1004 perror("ftp: bind"); 1005 goto bad; 1006 } 1007 if (options & SO_DEBUG && 1008 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0) 1009 perror("ftp: setsockopt (ignored)"); 1010 len = sizeof (data_addr); 1011 if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) { 1012 perror("ftp: getsockname"); 1013 goto bad; 1014 } 1015 if (listen(data, 1) < 0) 1016 perror("ftp: listen"); 1017 if (sendport) { 1018 a = (char *)&data_addr.sin_addr; 1019 p = (char *)&data_addr.sin_port; 1020 #define UC(b) (((int)b)&0xff) 1021 result = 1022 command("PORT %d,%d,%d,%d,%d,%d", 1023 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 1024 UC(p[0]), UC(p[1])); 1025 if (result == ERROR && sendport == -1) { 1026 sendport = 0; 1027 tmpno = 1; 1028 goto noport; 1029 } 1030 return (result != COMPLETE); 1031 } 1032 if (tmpno) 1033 sendport = 1; 1034 return (0); 1035 bad: 1036 (void) close(data), data = -1; 1037 if (tmpno) 1038 sendport = 1; 1039 return (1); 1040 } 1041 1042 FILE * 1043 dataconn(lmode) 1044 char *lmode; 1045 { 1046 struct sockaddr_in from; 1047 int s, fromlen = sizeof (from); 1048 1049 s = accept(data, (struct sockaddr *) &from, &fromlen); 1050 if (s < 0) { 1051 perror("ftp: accept"); 1052 (void) close(data), data = -1; 1053 return (NULL); 1054 } 1055 (void) close(data); 1056 data = s; 1057 return (fdopen(data, lmode)); 1058 } 1059 1060 ptransfer(direction, bytes, t0, t1) 1061 char *direction; 1062 long bytes; 1063 struct timeval *t0, *t1; 1064 { 1065 struct timeval td; 1066 float s, bs; 1067 1068 if (verbose) { 1069 tvsub(&td, t1, t0); 1070 s = td.tv_sec + (td.tv_usec / 1000000.); 1071 #define nz(x) ((x) == 0 ? 1 : (x)) 1072 bs = bytes / nz(s); 1073 printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n", 1074 bytes, direction, s, bs / 1024.); 1075 } 1076 } 1077 1078 /*tvadd(tsum, t0) 1079 struct timeval *tsum, *t0; 1080 { 1081 1082 tsum->tv_sec += t0->tv_sec; 1083 tsum->tv_usec += t0->tv_usec; 1084 if (tsum->tv_usec > 1000000) 1085 tsum->tv_sec++, tsum->tv_usec -= 1000000; 1086 } */ 1087 1088 tvsub(tdiff, t1, t0) 1089 struct timeval *tdiff, *t1, *t0; 1090 { 1091 1092 tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 1093 tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 1094 if (tdiff->tv_usec < 0) 1095 tdiff->tv_sec--, tdiff->tv_usec += 1000000; 1096 } 1097 1098 void 1099 psabort() 1100 { 1101 extern int abrtflag; 1102 1103 abrtflag++; 1104 } 1105 1106 pswitch(flag) 1107 int flag; 1108 { 1109 extern int proxy, abrtflag; 1110 sig_t oldintr; 1111 static struct comvars { 1112 int connect; 1113 char name[MAXHOSTNAMELEN]; 1114 struct sockaddr_in mctl; 1115 struct sockaddr_in hctl; 1116 FILE *in; 1117 FILE *out; 1118 int tpe; 1119 int curtpe; 1120 int cpnd; 1121 int sunqe; 1122 int runqe; 1123 int mcse; 1124 int ntflg; 1125 char nti[17]; 1126 char nto[17]; 1127 int mapflg; 1128 char mi[MAXPATHLEN]; 1129 char mo[MAXPATHLEN]; 1130 } proxstruct, tmpstruct; 1131 struct comvars *ip, *op; 1132 1133 abrtflag = 0; 1134 oldintr = signal(SIGINT, psabort); 1135 if (flag) { 1136 if (proxy) 1137 return; 1138 ip = &tmpstruct; 1139 op = &proxstruct; 1140 proxy++; 1141 } else { 1142 if (!proxy) 1143 return; 1144 ip = &proxstruct; 1145 op = &tmpstruct; 1146 proxy = 0; 1147 } 1148 ip->connect = connected; 1149 connected = op->connect; 1150 if (hostname) { 1151 (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1); 1152 ip->name[strlen(ip->name)] = '\0'; 1153 } else 1154 ip->name[0] = 0; 1155 hostname = op->name; 1156 ip->hctl = hisctladdr; 1157 hisctladdr = op->hctl; 1158 ip->mctl = myctladdr; 1159 myctladdr = op->mctl; 1160 ip->in = cin; 1161 cin = op->in; 1162 ip->out = cout; 1163 cout = op->out; 1164 ip->tpe = type; 1165 type = op->tpe; 1166 ip->curtpe = curtype; 1167 curtype = op->curtpe; 1168 ip->cpnd = cpend; 1169 cpend = op->cpnd; 1170 ip->sunqe = sunique; 1171 sunique = op->sunqe; 1172 ip->runqe = runique; 1173 runique = op->runqe; 1174 ip->mcse = mcase; 1175 mcase = op->mcse; 1176 ip->ntflg = ntflag; 1177 ntflag = op->ntflg; 1178 (void) strncpy(ip->nti, ntin, 16); 1179 (ip->nti)[strlen(ip->nti)] = '\0'; 1180 (void) strcpy(ntin, op->nti); 1181 (void) strncpy(ip->nto, ntout, 16); 1182 (ip->nto)[strlen(ip->nto)] = '\0'; 1183 (void) strcpy(ntout, op->nto); 1184 ip->mapflg = mapflag; 1185 mapflag = op->mapflg; 1186 (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1); 1187 (ip->mi)[strlen(ip->mi)] = '\0'; 1188 (void) strcpy(mapin, op->mi); 1189 (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1); 1190 (ip->mo)[strlen(ip->mo)] = '\0'; 1191 (void) strcpy(mapout, op->mo); 1192 (void) signal(SIGINT, oldintr); 1193 if (abrtflag) { 1194 abrtflag = 0; 1195 (*oldintr)(); 1196 } 1197 } 1198 1199 jmp_buf ptabort; 1200 int ptabflg; 1201 1202 void 1203 abortpt() 1204 { 1205 printf("\n"); 1206 (void) fflush(stdout); 1207 ptabflg++; 1208 mflag = 0; 1209 abrtflag = 0; 1210 longjmp(ptabort, 1); 1211 } 1212 1213 proxtrans(cmd, local, remote) 1214 char *cmd, *local, *remote; 1215 { 1216 sig_t oldintr; 1217 int secndflag = 0, prox_type, nfnd; 1218 extern jmp_buf ptabort; 1219 char *cmd2; 1220 struct fd_set mask; 1221 void abortpt(); 1222 1223 if (strcmp(cmd, "RETR")) 1224 cmd2 = "RETR"; 1225 else 1226 cmd2 = runique ? "STOU" : "STOR"; 1227 if ((prox_type = type) == 0) { 1228 if (unix_server && unix_proxy) 1229 prox_type = TYPE_I; 1230 else 1231 prox_type = TYPE_A; 1232 } 1233 if (curtype != prox_type) 1234 changetype(prox_type, 1); 1235 if (command("PASV") != COMPLETE) { 1236 printf("proxy server does not support third party transfers.\n"); 1237 return; 1238 } 1239 pswitch(0); 1240 if (!connected) { 1241 printf("No primary connection\n"); 1242 pswitch(1); 1243 code = -1; 1244 return; 1245 } 1246 if (curtype != prox_type) 1247 changetype(prox_type, 1); 1248 if (command("PORT %s", pasv) != COMPLETE) { 1249 pswitch(1); 1250 return; 1251 } 1252 if (setjmp(ptabort)) 1253 goto abort; 1254 oldintr = signal(SIGINT, abortpt); 1255 if (command("%s %s", cmd, remote) != PRELIM) { 1256 (void) signal(SIGINT, oldintr); 1257 pswitch(1); 1258 return; 1259 } 1260 sleep(2); 1261 pswitch(1); 1262 secndflag++; 1263 if (command("%s %s", cmd2, local) != PRELIM) 1264 goto abort; 1265 ptflag++; 1266 (void) getreply(0); 1267 pswitch(0); 1268 (void) getreply(0); 1269 (void) signal(SIGINT, oldintr); 1270 pswitch(1); 1271 ptflag = 0; 1272 printf("local: %s remote: %s\n", local, remote); 1273 return; 1274 abort: 1275 (void) signal(SIGINT, SIG_IGN); 1276 ptflag = 0; 1277 if (strcmp(cmd, "RETR") && !proxy) 1278 pswitch(1); 1279 else if (!strcmp(cmd, "RETR") && proxy) 1280 pswitch(0); 1281 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ 1282 if (command("%s %s", cmd2, local) != PRELIM) { 1283 pswitch(0); 1284 if (cpend) 1285 abort_remote((FILE *) NULL); 1286 } 1287 pswitch(1); 1288 if (ptabflg) 1289 code = -1; 1290 (void) signal(SIGINT, oldintr); 1291 return; 1292 } 1293 if (cpend) 1294 abort_remote((FILE *) NULL); 1295 pswitch(!proxy); 1296 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */ 1297 if (command("%s %s", cmd2, local) != PRELIM) { 1298 pswitch(0); 1299 if (cpend) 1300 abort_remote((FILE *) NULL); 1301 pswitch(1); 1302 if (ptabflg) 1303 code = -1; 1304 (void) signal(SIGINT, oldintr); 1305 return; 1306 } 1307 } 1308 if (cpend) 1309 abort_remote((FILE *) NULL); 1310 pswitch(!proxy); 1311 if (cpend) { 1312 FD_ZERO(&mask); 1313 FD_SET(fileno(cin), &mask); 1314 if ((nfnd = empty(&mask, 10)) <= 0) { 1315 if (nfnd < 0) { 1316 perror("abort"); 1317 } 1318 if (ptabflg) 1319 code = -1; 1320 lostpeer(); 1321 } 1322 (void) getreply(0); 1323 (void) getreply(0); 1324 } 1325 if (proxy) 1326 pswitch(0); 1327 pswitch(1); 1328 if (ptabflg) 1329 code = -1; 1330 (void) signal(SIGINT, oldintr); 1331 } 1332 1333 reset() 1334 { 1335 struct fd_set mask; 1336 int nfnd = 1; 1337 1338 FD_ZERO(&mask); 1339 while (nfnd > 0) { 1340 FD_SET(fileno(cin), &mask); 1341 if ((nfnd = empty(&mask,0)) < 0) { 1342 perror("reset"); 1343 code = -1; 1344 lostpeer(); 1345 } 1346 else if (nfnd) { 1347 (void) getreply(0); 1348 } 1349 } 1350 } 1351 1352 char * 1353 gunique(local) 1354 char *local; 1355 { 1356 static char new[MAXPATHLEN]; 1357 char *cp = rindex(local, '/'); 1358 int d, count=0; 1359 char ext = '1'; 1360 1361 if (cp) 1362 *cp = '\0'; 1363 d = access(cp ? local : ".", 2); 1364 if (cp) 1365 *cp = '/'; 1366 if (d < 0) { 1367 fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); 1368 return((char *) 0); 1369 } 1370 (void) strcpy(new, local); 1371 cp = new + strlen(new); 1372 *cp++ = '.'; 1373 while (!d) { 1374 if (++count == 100) { 1375 printf("runique: can't find unique file name.\n"); 1376 return((char *) 0); 1377 } 1378 *cp++ = ext; 1379 *cp = '\0'; 1380 if (ext == '9') 1381 ext = '0'; 1382 else 1383 ext++; 1384 if ((d = access(new, 0)) < 0) 1385 break; 1386 if (ext != '0') 1387 cp--; 1388 else if (*(cp - 2) == '.') 1389 *(cp - 1) = '1'; 1390 else { 1391 *(cp - 2) = *(cp - 2) + 1; 1392 cp--; 1393 } 1394 } 1395 return(new); 1396 } 1397 1398 abort_remote(din) 1399 FILE *din; 1400 { 1401 char buf[BUFSIZ]; 1402 int nfnd; 1403 struct fd_set mask; 1404 1405 /* 1406 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark 1407 * after urgent byte rather than before as is protocol now 1408 */ 1409 sprintf(buf, "%c%c%c", IAC, IP, IAC); 1410 if (send(fileno(cout), buf, 3, MSG_OOB) != 3) 1411 perror("abort"); 1412 fprintf(cout,"%cABOR\r\n", DM); 1413 (void) fflush(cout); 1414 FD_ZERO(&mask); 1415 FD_SET(fileno(cin), &mask); 1416 if (din) { 1417 FD_SET(fileno(din), &mask); 1418 } 1419 if ((nfnd = empty(&mask, 10)) <= 0) { 1420 if (nfnd < 0) { 1421 perror("abort"); 1422 } 1423 if (ptabflg) 1424 code = -1; 1425 lostpeer(); 1426 } 1427 if (din && FD_ISSET(fileno(din), &mask)) { 1428 while (read(fileno(din), buf, BUFSIZ) > 0) 1429 /* LOOP */; 1430 } 1431 if (getreply(0) == ERROR && code == 552) { 1432 /* 552 needed for nic style abort */ 1433 (void) getreply(0); 1434 } 1435 (void) getreply(0); 1436 } 1437