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