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