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