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