[FTP]
[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 #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(const 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 == INVALID_SOCKET) {
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);
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 == 0) {
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);
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 (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)();
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)
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)();
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;
749 struct timeval start, stop;
750 // struct stat st;
751
752 is_retr = strcmp(cmd, "RETR") == 0;
753 if (is_retr && verbose && printnames) {
754 if (local && *local != '-')
755 printf("local: %s ", local);
756 if (remote)
757 printf("remote: %s\n", remote);
758 (void) fflush(stdout);
759 }
760 if (proxy && is_retr) {
761 proxtrans(cmd, local, remote);
762 return;
763 }
764 closefunc = NULL;
765 oldintr = NULL;
766 oldintp = NULL;
767 tcrflag = !crflag && is_retr;
768 if (setjmp(recvabort)) {
769 while (cpend) {
770 (void) getreply(0);
771 }
772 if (data >= 0) {
773 (void) close(data);
774 data = -1;
775 }
776 if (oldintr)
777 null();// (void) signal(SIGINT, oldintr);
778 code = -1;
779 return;
780 }
781 null();// oldintr = signal(SIGINT, abortrecv);
782 if (strcmp(local, "-") && *local != '|') {
783 #ifndef _WIN32
784 register int d;
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(0, NULL);
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(0, NULL);
856 break;
857 case TYPE_E:
858 setebcdic();
859 break;
860 case TYPE_L:
861 settenex(0, NULL);
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(0, NULL);
877 break;
878 case TYPE_E:
879 setebcdic();
880 break;
881 case TYPE_L:
882 settenex(0, NULL);
883 break;
884 }
885 verbose = oldverbose;
886 }
887 return;
888 }
889 }
890 din = dataconn("r");
891 if (!din)
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 = 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(0, NULL);
1048 break;
1049 case TYPE_E:
1050 setebcdic();
1051 break;
1052 case TYPE_L:
1053 settenex(0, NULL);
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(0, NULL);
1073 break;
1074 case TYPE_E:
1075 setebcdic();
1076 break;
1077 case TYPE_L:
1078 settenex(0, NULL);
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 (recv(din, buf, bufsize, 0) > 0)
1111 ;
1112 }
1113 if (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 int
1141 initconn()
1142 {
1143 register char *p, *a;
1144 int result, len, tmpno = 0;
1145 int on = 1;
1146 int a0, a1, a2, a3, p0, p1;
1147
1148
1149 if (passivemode) {
1150 data = socket(AF_INET, SOCK_STREAM, 0);
1151 if (data < 0) {
1152 perror("ftp: socket");
1153 return(1);
1154 }
1155 if ((options & SO_DEBUG) &&
1156 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
1157 sizeof (on)) < 0)
1158 perror("ftp: setsockopt (ignored)");
1159 if (command("PASV") != COMPLETE) {
1160 printf("Passive mode refused.\n");
1161 goto bad;
1162 }
1163
1164 /*
1165 * What we've got at this point is a string of comma
1166 * separated one-byte unsigned integer values.
1167 * The first four are the an IP address. The fifth is
1168 * the MSB of the port number, the sixth is the LSB.
1169 * From that we'll prepare a sockaddr_in.
1170 */
1171
1172 if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",
1173 &a0, &a1, &a2, &a3, &p0, &p1) != 6) {
1174 printf("Passive mode address scan failure. Shouldn't happen!\n");
1175 goto bad;
1176 }
1177
1178 bzero(&data_addr, sizeof(data_addr));
1179 data_addr.sin_family = AF_INET;
1180 a = (char *)&data_addr.sin_addr.s_addr;
1181 a[0] = a0 & 0xff;
1182 a[1] = a1 & 0xff;
1183 a[2] = a2 & 0xff;
1184 a[3] = a3 & 0xff;
1185 p = (char *)&data_addr.sin_port;
1186 p[0] = p0 & 0xff;
1187 p[1] = p1 & 0xff;
1188
1189 if (connect(data, (struct sockaddr *)&data_addr,
1190 sizeof(data_addr)) < 0) {
1191 perror("ftp: connect");
1192 goto bad;
1193 }
1194 return(0);
1195 }
1196
1197
1198 noport:
1199 data_addr = myctladdr;
1200 if (sendport)
1201 data_addr.sin_port = 0; /* let system pick one */
1202 if (data != -1)
1203 (void) close (data);
1204 data = socket(AF_INET, SOCK_STREAM, 0);
1205 if (data < 0) {
1206 perror("ftp: socket");
1207 if (tmpno)
1208 sendport = 1;
1209 return (1);
1210 }
1211 if (!sendport)
1212 if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
1213 perror("ftp: setsockopt (reuse address)");
1214 goto bad;
1215 }
1216 if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
1217 perror("ftp: bind");
1218 goto bad;
1219 }
1220 if (options & SO_DEBUG &&
1221 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
1222 perror("ftp: setsockopt (ignored)");
1223 len = sizeof (data_addr);
1224 if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
1225 perror("ftp: getsockname");
1226 goto bad;
1227 }
1228 if (listen(data, 1) < 0)
1229 perror("ftp: listen");
1230 if (sendport) {
1231 a = (char *)&data_addr.sin_addr;
1232 p = (char *)&data_addr.sin_port;
1233 #define UC(b) (((int)b)&0xff)
1234 result =
1235 command("PORT %d,%d,%d,%d,%d,%d",
1236 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
1237 UC(p[0]), UC(p[1]));
1238 if (result == ERROR && sendport == -1) {
1239 sendport = 0;
1240 tmpno = 1;
1241 goto noport;
1242 }
1243 return (result != COMPLETE);
1244 }
1245 if (tmpno)
1246 sendport = 1;
1247 return (0);
1248 bad:
1249 (void) fflush(stdout);
1250 (void) close(data), data = -1;
1251 if (tmpno)
1252 sendport = 1;
1253 return (1);
1254 }
1255
1256 int dataconn(const char *mode)
1257 {
1258 struct sockaddr_in from;
1259 int s, fromlen = sizeof (from);
1260
1261 if (passivemode)
1262 return (data);
1263
1264 s = accept(data, (struct sockaddr *) &from, &fromlen);
1265 if (s < 0) {
1266 perror("ftp: accept");
1267 (void) closesocket(data), data = -1;
1268 return 0;
1269 }
1270 if(closesocket(data)) {
1271 int iret=WSAGetLastError ();
1272 fprintf(stdout,"Error closing socket(%d)\n",iret);
1273 (void) fflush(stdout);
1274 }
1275
1276 data = s;
1277 return (data);
1278 }
1279
1280 void ptransfer(direction, bytes, t0, t1)
1281 const char *direction;
1282 long bytes;
1283 struct timeval *t0, *t1;
1284 {
1285 struct timeval td;
1286 double s, bs;
1287
1288 if (verbose) {
1289 tvsub(&td, t1, t0);
1290 s = td.tv_sec + (td.tv_usec / 1000000.);
1291 #define nz(x) ((x) == 0 ? 1 : (x))
1292 bs = bytes / nz(s);
1293 printf("%ld bytes %s in %.1f seconds (%.0f Kbytes/s)\n",
1294 bytes, direction, s, bs / 1024.);
1295 (void) fflush(stdout);
1296 }
1297 }
1298
1299 /*tvadd(tsum, t0)
1300 struct timeval *tsum, *t0;
1301 {
1302
1303 tsum->tv_sec += t0->tv_sec;
1304 tsum->tv_usec += t0->tv_usec;
1305 if (tsum->tv_usec > 1000000)
1306 tsum->tv_sec++, tsum->tv_usec -= 1000000;
1307 } */
1308
1309 void tvsub(tdiff, t1, t0)
1310 struct timeval *tdiff, *t1, *t0;
1311 {
1312
1313 tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
1314 tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
1315 if (tdiff->tv_usec < 0)
1316 tdiff->tv_sec--, tdiff->tv_usec += 1000000;
1317 }
1318
1319 void psabort(int flag)
1320 {
1321 extern int abrtflag;
1322
1323 abrtflag++;
1324 }
1325
1326 void pswitch(int flag)
1327 {
1328 extern int proxy, abrtflag;
1329 Sig_t oldintr;
1330 static struct comvars {
1331 int connect;
1332 char name[MAXHOSTNAMELEN];
1333 struct sockaddr_in mctl;
1334 struct sockaddr_in hctl;
1335 SOCKET in;
1336 SOCKET out;
1337 int tpe;
1338 int cpnd;
1339 int sunqe;
1340 int runqe;
1341 int mcse;
1342 int ntflg;
1343 char nti[17];
1344 char nto[17];
1345 int mapflg;
1346 char mi[MAXPATHLEN];
1347 char mo[MAXPATHLEN];
1348 } proxstruct, tmpstruct;
1349 struct comvars *ip, *op;
1350
1351 abrtflag = 0;
1352 oldintr = signal(SIGINT, psabort);
1353 if (flag) {
1354 if (proxy)
1355 return;
1356 ip = &tmpstruct;
1357 op = &proxstruct;
1358 proxy++;
1359 }
1360 else {
1361 if (!proxy)
1362 return;
1363 ip = &proxstruct;
1364 op = &tmpstruct;
1365 proxy = 0;
1366 }
1367 ip->connect = connected;
1368 connected = op->connect;
1369 if (hostname) {
1370 (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
1371 ip->name[strlen(ip->name)] = '\0';
1372 } else
1373 ip->name[0] = 0;
1374 hostname = op->name;
1375 ip->hctl = hisctladdr;
1376 hisctladdr = op->hctl;
1377 ip->mctl = myctladdr;
1378 myctladdr = op->mctl;
1379 ip->in = cin;
1380 cin = op->in;
1381 ip->out = cout;
1382 cout = op->out;
1383 ip->tpe = type;
1384 type = op->tpe;
1385 if (!type)
1386 type = 1;
1387 ip->cpnd = cpend;
1388 cpend = op->cpnd;
1389 ip->sunqe = sunique;
1390 sunique = op->sunqe;
1391 ip->runqe = runique;
1392 runique = op->runqe;
1393 ip->mcse = mcase;
1394 mcase = op->mcse;
1395 ip->ntflg = ntflag;
1396 ntflag = op->ntflg;
1397 (void) strncpy(ip->nti, ntin, 16);
1398 (ip->nti)[strlen(ip->nti)] = '\0';
1399 (void) strcpy(ntin, op->nti);
1400 (void) strncpy(ip->nto, ntout, 16);
1401 (ip->nto)[strlen(ip->nto)] = '\0';
1402 (void) strcpy(ntout, op->nto);
1403 ip->mapflg = mapflag;
1404 mapflag = op->mapflg;
1405 (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
1406 (ip->mi)[strlen(ip->mi)] = '\0';
1407 (void) strcpy(mapin, op->mi);
1408 (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
1409 (ip->mo)[strlen(ip->mo)] = '\0';
1410 (void) strcpy(mapout, op->mo);
1411 // (void) signal(SIGINT, oldintr);
1412 if (abrtflag) {
1413 abrtflag = 0;
1414 (*oldintr)(1);
1415 }
1416 }
1417
1418 jmp_buf ptabort;
1419 int ptabflg;
1420
1421 #if 0
1422 void
1423 abortpt()
1424 {
1425 printf("\n");
1426 (void) fflush(stdout);
1427 ptabflg++;
1428 mflag = 0;
1429 abrtflag = 0;
1430 longjmp(ptabort, 1);
1431 }
1432 #endif
1433
1434 void proxtrans(cmd, local, remote)
1435 const char *cmd, *local, *remote;
1436 {
1437 // void (*oldintr)(int);
1438 int tmptype, oldtype = 0, secndflag = 0, nfnd;
1439 extern jmp_buf ptabort;
1440 const char *cmd2;
1441 // struct
1442 fd_set mask;
1443
1444 if (strcmp(cmd, "RETR"))
1445 cmd2 = "RETR";
1446 else
1447 cmd2 = runique ? "STOU" : "STOR";
1448 if (command("PASV") != COMPLETE) {
1449 printf("proxy server does not support third part transfers.\n");
1450 (void) fflush(stdout);
1451 return;
1452 }
1453 tmptype = type;
1454 pswitch(0);
1455 if (!connected) {
1456 printf("No primary connection\n");
1457 (void) fflush(stdout);
1458 pswitch(1);
1459 code = -1;
1460 return;
1461 }
1462 if (type != tmptype) {
1463 oldtype = type;
1464 switch (tmptype) {
1465 case TYPE_A:
1466 setascii(0, NULL);
1467 break;
1468 case TYPE_I:
1469 setbinary(0, NULL);
1470 break;
1471 case TYPE_E:
1472 setebcdic();
1473 break;
1474 case TYPE_L:
1475 settenex(0, NULL);
1476 break;
1477 }
1478 }
1479 if (command("PORT %s", pasv) != COMPLETE) {
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 if (setjmp(ptabort))
1500 goto abort;
1501 null();// oldintr = signal(SIGINT, abortpt);
1502 if (command("%s %s", cmd, remote) != PRELIM) {
1503 null();// (void) signal(SIGINT, oldintr);
1504 switch (oldtype) {
1505 case 0:
1506 break;
1507 case TYPE_A:
1508 setascii(0, NULL);
1509 break;
1510 case TYPE_I:
1511 setbinary(0, NULL);
1512 break;
1513 case TYPE_E:
1514 setebcdic();
1515 break;
1516 case TYPE_L:
1517 settenex(0, NULL);
1518 break;
1519 }
1520 pswitch(1);
1521 return;
1522 }
1523 sleep(2);
1524 pswitch(1);
1525 secndflag++;
1526 if (command("%s %s", cmd2, local) != PRELIM)
1527 goto abort;
1528 ptflag++;
1529 (void) getreply(0);
1530 pswitch(0);
1531 (void) getreply(0);
1532 null();// (void) signal(SIGINT, oldintr);
1533 switch (oldtype) {
1534 case 0:
1535 break;
1536 case TYPE_A:
1537 setascii(0, NULL);
1538 break;
1539 case TYPE_I:
1540 setbinary(0, NULL);
1541 break;
1542 case TYPE_E:
1543 setebcdic();
1544 break;
1545 case TYPE_L:
1546 settenex(0, NULL);
1547 break;
1548 }
1549 pswitch(1);
1550 ptflag = 0;
1551 printf("local: %s remote: %s\n", local, remote);
1552 (void) fflush(stdout);
1553 return;
1554 abort:
1555 null();// (void) signal(SIGINT, SIG_IGN);
1556 ptflag = 0;
1557 if (strcmp(cmd, "RETR") && !proxy)
1558 pswitch(1);
1559 else if (!strcmp(cmd, "RETR") && proxy)
1560 pswitch(0);
1561 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
1562 if (command("%s %s", cmd2, local) != PRELIM) {
1563 pswitch(0);
1564 switch (oldtype) {
1565 case 0:
1566 break;
1567 case TYPE_A:
1568 setascii(0, NULL);
1569 break;
1570 case TYPE_I:
1571 setbinary(0, NULL);
1572 break;
1573 case TYPE_E:
1574 setebcdic();
1575 break;
1576 case TYPE_L:
1577 settenex(0, NULL);
1578 break;
1579 }
1580 if (cpend) {
1581 char msg[2];
1582
1583 fprintfSocket(cout,"%c%c",IAC,IP);
1584 *msg = (char) IAC;
1585 *(msg+1) = (char) DM;
1586 if (send(cout,msg,2,MSG_OOB) != 2)
1587 perror("abort");
1588 fprintfSocket(cout,"ABOR\r\n");
1589 FD_ZERO(&mask);
1590 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this
1591 if ((nfnd = empty(&mask,10)) <= 0) {
1592 if (nfnd < 0) {
1593 perror("abort");
1594 }
1595 if (ptabflg)
1596 code = -1;
1597 lostpeer();
1598 }
1599 (void) getreply(0);
1600 (void) getreply(0);
1601 }
1602 }
1603 pswitch(1);
1604 if (ptabflg)
1605 code = -1;
1606 null();// (void) signal(SIGINT, oldintr);
1607 return;
1608 }
1609 if (cpend) {
1610 char msg[2];
1611
1612 fprintfSocket(cout,"%c%c",IAC,IP);
1613 *msg = (char)IAC;
1614 *(msg+1) = (char)DM;
1615 if (send(cout,msg,2,MSG_OOB) != 2)
1616 perror("abort");
1617 fprintfSocket(cout,"ABOR\r\n");
1618 FD_ZERO(&mask);
1619 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this...
1620 if ((nfnd = empty(&mask,10)) <= 0) {
1621 if (nfnd < 0) {
1622 perror("abort");
1623 }
1624 if (ptabflg)
1625 code = -1;
1626 lostpeer();
1627 }
1628 (void) getreply(0);
1629 (void) getreply(0);
1630 }
1631 pswitch(!proxy);
1632 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
1633 if (command("%s %s", cmd2, local) != PRELIM) {
1634 pswitch(0);
1635 switch (oldtype) {
1636 case 0:
1637 break;
1638 case TYPE_A:
1639 setascii(0, NULL);
1640 break;
1641 case TYPE_I:
1642 setbinary(0, NULL);
1643 break;
1644 case TYPE_E:
1645 setebcdic();
1646 break;
1647 case TYPE_L:
1648 settenex(0, NULL);
1649 break;
1650 }
1651 if (cpend) {
1652 char msg[2];
1653
1654 fprintfSocket(cout,"%c%c",IAC,IP);
1655 *msg = (char)IAC;
1656 *(msg+1) = (char)DM;
1657 if (send(cout,msg,2,MSG_OOB) != 2)
1658 perror("abort");
1659 fprintfSocket(cout,"ABOR\r\n");
1660 FD_ZERO(&mask);
1661 // FD_SET(fileno(cin), &mask); // Chris:
1662 if ((nfnd = empty(&mask,10)) <= 0) {
1663 if (nfnd < 0) {
1664 perror("abort");
1665 }
1666 if (ptabflg)
1667 code = -1;
1668 lostpeer();
1669 }
1670 (void) getreply(0);
1671 (void) getreply(0);
1672 }
1673 pswitch(1);
1674 if (ptabflg)
1675 code = -1;
1676 null();// (void) signal(SIGINT, oldintr);
1677 return;
1678 }
1679 }
1680 if (cpend) {
1681 char msg[2];
1682
1683 fprintfSocket(cout,"%c%c",IAC,IP);
1684 *msg = (char)IAC;
1685 *(msg+1) = (char)DM;
1686 if (send(cout,msg,2,MSG_OOB) != 2)
1687 perror("abort");
1688 fprintfSocket(cout,"ABOR\r\n");
1689 FD_ZERO(&mask);
1690 // FD_SET(fileno(cin), &mask); // Chris:
1691 if ((nfnd = empty(&mask,10)) <= 0) {
1692 if (nfnd < 0) {
1693 perror("abort");
1694 }
1695 if (ptabflg)
1696 code = -1;
1697 lostpeer();
1698 }
1699 (void) getreply(0);
1700 (void) getreply(0);
1701 }
1702 pswitch(!proxy);
1703 if (cpend) {
1704 FD_ZERO(&mask);
1705 // FD_SET(fileno(cin), &mask); // Chris:
1706 if ((nfnd = empty(&mask,10)) <= 0) {
1707 if (nfnd < 0) {
1708 perror("abort");
1709 }
1710 if (ptabflg)
1711 code = -1;
1712 lostpeer();
1713 }
1714 (void) getreply(0);
1715 (void) getreply(0);
1716 }
1717 if (proxy)
1718 pswitch(0);
1719 switch (oldtype) {
1720 case 0:
1721 break;
1722 case TYPE_A:
1723 setascii(0, NULL);
1724 break;
1725 case TYPE_I:
1726 setbinary(0, NULL);
1727 break;
1728 case TYPE_E:
1729 setebcdic();
1730 break;
1731 case TYPE_L:
1732 settenex(0, NULL);
1733 break;
1734 }
1735 pswitch(1);
1736 if (ptabflg)
1737 code = -1;
1738 null();// (void) signal(SIGINT, oldintr);
1739 }
1740
1741 void reset(int argc, const char *argv[])
1742 {
1743 // struct
1744 fd_set mask;
1745 int nfnd = 1;
1746
1747 FD_ZERO(&mask);
1748 while (nfnd > 0) {
1749 // FD_SET(fileno(cin), &mask); // Chris
1750 if ((nfnd = empty(&mask,0)) < 0) {
1751 perror("reset");
1752 code = -1;
1753 lostpeer();
1754 }
1755 else if (nfnd) {
1756 (void) getreply(0);
1757 }
1758 }
1759 }
1760
1761 #if 0
1762 char *
1763 gunique(local)
1764 char *local;
1765 {
1766 static char new[MAXPATHLEN];
1767 char *cp = rindex(local, '/');
1768 int d, count=0;
1769 char ext = '1';
1770
1771 if (cp)
1772 *cp = '\0';
1773 d = access(cp ? local : ".", 2);
1774 if (cp)
1775 *cp = '/';
1776 if (d < 0) {
1777 perror(local);
1778 return((char *) 0);
1779 }
1780 (void) strcpy(new, local);
1781 cp = new + strlen(new);
1782 *cp++ = '.';
1783 while (!d) {
1784 if (++count == 100) {
1785 printf("runique: can't find unique file name.\n");
1786 (void) fflush(stdout);
1787 return((char *) 0);
1788 }
1789 *cp++ = ext;
1790 *cp = '\0';
1791 if (ext == '9')
1792 ext = '0';
1793 else
1794 ext++;
1795 if ((d = access(new, 0)) < 0)
1796 break;
1797 if (ext != '0')
1798 cp--;
1799 else if (*(cp - 2) == '.')
1800 *(cp - 1) = '1';
1801 else {
1802 *(cp - 2) = *(cp - 2) + 1;
1803 cp--;
1804 }
1805 }
1806 return(new);
1807 }
1808 #endif
1809
1810 int null(void)
1811 {
1812 return 0;
1813 }