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