|
|
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.