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