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