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