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