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