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