Create a branch for header work.
[reactos.git] / 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(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 (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)();
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, d;
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 // This whole thing is a problem... access Won't work on non-existent files
785 if (access(local, 2) < 0) {
786 char *dir = rindex(local, '/');
787
788 if (errno != ENOENT && errno != EACCES) {
789 perror(local);
790 (void) signal(SIGINT, oldintr);
791 code = -1;
792 return;
793 }
794 if (dir != NULL)
795 *dir = 0;
796 d = access(dir ? local : ".", 2);
797 if (dir != NULL)
798 *dir = '/';
799 if (d < 0) {
800 perror(local);
801 (void) signal(SIGINT, oldintr);
802 code = -1;
803 return;
804 }
805 if (!runique && errno == EACCES &&
806 chmod(local, 0600) < 0) {
807 perror(local);
808 (void) signal(SIGINT, oldintr);
809 code = -1;
810 return;
811 }
812 if (runique && errno == EACCES &&
813 (local = gunique(local)) == NULL) {
814 (void) signal(SIGINT, oldintr);
815 code = -1;
816 return;
817 }
818 }
819 else if (runique && (local = gunique(local)) == NULL) {
820 (void) signal(SIGINT, oldintr);
821 code = -1;
822 return;
823 }
824 #endif
825 }
826 if (initconn()) {
827 null();// (void) signal(SIGINT, oldintr);
828 code = -1;
829 return;
830 }
831 if (setjmp(recvabort))
832 goto abort;
833 if (!is_retr) {
834 if (type != TYPE_A && (allbinary == 0 || type != TYPE_I)) {
835 oldtype = type;
836 oldverbose = verbose;
837 if (!debug)
838 verbose = 0;
839 setascii();
840 verbose = oldverbose;
841 }
842 } else if (restart_point) {
843 if (command("REST %ld", (long) restart_point) != CONTINUE)
844 return;
845 }
846 if (remote) {
847 if (command("%s %s", cmd, remote) != PRELIM) {
848 null();// (void) signal(SIGINT, oldintr);
849 if (oldtype) {
850 if (!debug)
851 verbose = 0;
852 switch (oldtype) {
853 case TYPE_I:
854 setbinary();
855 break;
856 case TYPE_E:
857 setebcdic();
858 break;
859 case TYPE_L:
860 settenex();
861 break;
862 }
863 verbose = oldverbose;
864 }
865 return;
866 }
867 } else {
868 if (command("%s", cmd) != PRELIM) {
869 null();// (void) signal(SIGINT, oldintr);
870 if (oldtype) {
871 if (!debug)
872 verbose = 0;
873 switch (oldtype) {
874 case TYPE_I:
875 setbinary();
876 break;
877 case TYPE_E:
878 setebcdic();
879 break;
880 case TYPE_L:
881 settenex();
882 break;
883 }
884 verbose = oldverbose;
885 }
886 return;
887 }
888 }
889 din = dataconn("r");
890 if (!din)
891 goto abort;
892 if (strcmp(local, "-") == 0)
893 fout = stdout;
894 else if (*local == '|') {
895 null();// oldintp = signal(SIGPIPE, SIG_IGN);
896 fout = _popen(local + 1, "w");
897 if (fout == NULL) {
898 perror(local+1);
899 goto abort;
900 }
901 closefunc = _pclose;
902 } else {
903 fout = fopen(local, mode);
904 if (fout == NULL) {
905 perror(local);
906 goto abort;
907 }
908 closefunc = fclose;
909 }
910 (void) gettimeofday(&start, (struct timezone *)0);
911 switch (type) {
912
913 case TYPE_I:
914 case TYPE_L:
915 if (restart_point &&
916 lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
917 perror(local);
918 if (closefunc != NULL)
919 (*closefunc)(fout);
920 return;
921 }
922 errno = d = 0;
923 // while ((c = recv(din, buf, bufsize, 1)) > 0) {
924 // if ((d = write(fileno(fout), buf, c)) != c)
925 // if ((d = write(fileno(fout), buf, c)) != c)
926 // break;
927 while ((c = recv(din, buf, bufsize, 0)) > 0) {
928 write(fileno(fout), buf, c);
929 bytes += c;
930 if (hash) {
931 while (bytes >= hashbytes) {
932 (void) putchar('#');
933 hashbytes += HASHBYTES;
934 }
935 (void) fflush(stdout);
936 }
937 }
938 if (hash && bytes > 0) {
939 if (bytes < HASHBYTES)
940 (void) putchar('#');
941 (void) putchar('\n');
942 (void) fflush(stdout);
943 }
944 // if (c < 0) {
945 // if (errno != EPIPE)
946 // perror("netin");
947 // bytes = -1;
948 // }
949 // if (d < c) {
950 // if (d < 0)
951 // perror(local);
952 // else
953 // fprintf(stderr, "%s: short write\n", local);
954 // }
955 break;
956
957 case TYPE_A:
958 if (restart_point) {
959 register int i, n, c;
960
961 if (fseek(fout, 0L, L_SET) < 0)
962 goto done;
963 n = restart_point;
964 i = 0;
965 while (i++ < n) {
966 if ((c=getc(fout)) == EOF)
967 goto done;
968 if (c == '\n')
969 i++;
970 }
971 if (fseek(fout, 0L, L_INCR) < 0) {
972 done:
973 perror(local);
974 if (closefunc != NULL)
975 (*closefunc)(fout);
976 return;
977 }
978 }
979 while ((c = fgetcSocket(din)) != EOF) {
980 if (c == '\n')
981 bare_lfs++;
982 while (c == '\r') {
983 while (hash && (bytes >= hashbytes)) {
984 (void) putchar('#');
985 (void) fflush(stdout);
986 hashbytes += HASHBYTES;
987 }
988 bytes++;
989 if ((c = fgetcSocket(din)) != '\n' || tcrflag) {
990 if (ferror(fout))
991 goto break2;
992 (void) putc('\r', fout);
993 if (c == '\0') {
994 bytes++;
995 goto contin2;
996 }
997 if (c == EOF)
998 goto contin2;
999 }
1000 }
1001 (void) putc(c, fout);
1002 bytes++;
1003 contin2: ;
1004 }
1005 break2:
1006 if (bare_lfs) {
1007 printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
1008 printf("File may not have transferred correctly.\n");
1009 (void) fflush(stdout);
1010 }
1011 if (hash) {
1012 if (bytes < hashbytes)
1013 (void) putchar('#');
1014 (void) putchar('\n');
1015 (void) fflush(stdout);
1016 }
1017 // if (ferror(din)) {
1018 // if (errno != EPIPE)
1019 // perror("netin");
1020 // bytes = -1;
1021 // }
1022 if (ferror(fout))
1023 perror(local);
1024 break;
1025 }
1026 if (closefunc != NULL)
1027 (*closefunc)(fout);
1028 null();// (void) signal(SIGINT, oldintr);
1029 if (oldintp)
1030 null();// (void) signal(SIGPIPE, oldintp);
1031 (void) gettimeofday(&stop, (struct timezone *)0);
1032 if(closesocket(din)) {
1033 int iret=WSAGetLastError ();
1034 fprintf(stdout,"Error closing socket(%d)\n",iret);
1035 (void) fflush(stdout);
1036 }
1037
1038 (void) getreply(0);
1039 if (bytes > 0 && is_retr)
1040 ptransfer("received", bytes, &start, &stop);
1041 if (oldtype) {
1042 if (!debug)
1043 verbose = 0;
1044 switch (oldtype) {
1045 case TYPE_I:
1046 setbinary();
1047 break;
1048 case TYPE_E:
1049 setebcdic();
1050 break;
1051 case TYPE_L:
1052 settenex();
1053 break;
1054 }
1055 verbose = oldverbose;
1056 }
1057 return;
1058 abort:
1059
1060 /* abort using RFC959 recommended IP,SYNC sequence */
1061
1062 (void) gettimeofday(&stop, (struct timezone *)0);
1063 if (oldintp)
1064 null();// (void) signal(SIGPIPE, oldintr);
1065 null();// (void) signal(SIGINT,SIG_IGN);
1066 if (oldtype) {
1067 if (!debug)
1068 verbose = 0;
1069 switch (oldtype) {
1070 case TYPE_I:
1071 setbinary();
1072 break;
1073 case TYPE_E:
1074 setebcdic();
1075 break;
1076 case TYPE_L:
1077 settenex();
1078 break;
1079 }
1080 verbose = oldverbose;
1081 }
1082 if (!cpend) {
1083 code = -1;
1084 null();// (void) signal(SIGINT,oldintr);
1085 return;
1086 }
1087
1088 fprintfSocket(cout,"%c%c",IAC,IP);
1089 msg = (char)IAC;
1090 /* send IAC in urgent mode instead of DM because UNIX places oob mark */
1091 /* after urgent byte rather than before as now is protocol */
1092 if (send(cout,&msg,1,MSG_OOB) != 1) {
1093 perror("abort");
1094 }
1095 fprintfSocket(cout,"%cABOR\r\n",DM);
1096 FD_ZERO(&mask);
1097 FD_SET(cin, &mask); // Need to correct this
1098 if (din) {
1099 FD_SET(din, &mask); // Need to correct this
1100 }
1101 if ((nfnd = empty(&mask,10)) <= 0) {
1102 if (nfnd < 0) {
1103 perror("abort");
1104 }
1105 code = -1;
1106 lostpeer();
1107 }
1108 if (din && FD_ISSET(din, &mask)) {
1109 while ((c = recv(din, buf, bufsize, 0)) > 0)
1110 ;
1111 }
1112 if ((c = getreply(0)) == ERROR && code == 552) { /* needed for nic style abort */
1113 if (data >= 0) {
1114 (void) close(data);
1115 data = -1;
1116 }
1117 (void) getreply(0);
1118 }
1119 (void) getreply(0);
1120 code = -1;
1121 if (data >= 0) {
1122 (void) close(data);
1123 data = -1;
1124 }
1125 if (closefunc != NULL && fout != NULL)
1126 (*closefunc)(fout);
1127 if (din)
1128 if(closesocket(din)) {
1129 int iret=WSAGetLastError ();
1130 fprintf(stdout,"Error closing socket(%d)\n",iret);
1131 (void) fflush(stdout);
1132 }
1133
1134 if (bytes > 0)
1135 ptransfer("received", bytes, &start, &stop);
1136 null();// (void) signal(SIGINT,oldintr);
1137 }
1138
1139 int
1140 initconn()
1141 {
1142 register char *p, *a;
1143 int result, len, tmpno = 0;
1144 int on = 1;
1145 int a0, a1, a2, a3, p0, p1;
1146
1147
1148 if (passivemode) {
1149 data = socket(AF_INET, SOCK_STREAM, 0);
1150 if (data < 0) {
1151 perror("ftp: socket");
1152 return(1);
1153 }
1154 if ((options & SO_DEBUG) &&
1155 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
1156 sizeof (on)) < 0)
1157 perror("ftp: setsockopt (ignored)");
1158 if (command("PASV") != COMPLETE) {
1159 printf("Passive mode refused.\n");
1160 goto bad;
1161 }
1162
1163 /*
1164 * What we've got at this point is a string of comma
1165 * separated one-byte unsigned integer values.
1166 * The first four are the an IP address. The fifth is
1167 * the MSB of the port number, the sixth is the LSB.
1168 * From that we'll prepare a sockaddr_in.
1169 */
1170
1171 if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",
1172 &a0, &a1, &a2, &a3, &p0, &p1) != 6) {
1173 printf("Passive mode address scan failure. Shouldn't happen!\n");
1174 goto bad;
1175 }
1176
1177 bzero(&data_addr, sizeof(data_addr));
1178 data_addr.sin_family = AF_INET;
1179 a = (char *)&data_addr.sin_addr.s_addr;
1180 a[0] = a0 & 0xff;
1181 a[1] = a1 & 0xff;
1182 a[2] = a2 & 0xff;
1183 a[3] = a3 & 0xff;
1184 p = (char *)&data_addr.sin_port;
1185 p[0] = p0 & 0xff;
1186 p[1] = p1 & 0xff;
1187
1188 if (connect(data, (struct sockaddr *)&data_addr,
1189 sizeof(data_addr)) < 0) {
1190 perror("ftp: connect");
1191 goto bad;
1192 }
1193 return(0);
1194 }
1195
1196
1197 noport:
1198 data_addr = myctladdr;
1199 if (sendport)
1200 data_addr.sin_port = 0; /* let system pick one */
1201 if (data != -1)
1202 (void) close (data);
1203 data = socket(AF_INET, SOCK_STREAM, 0);
1204 if (data < 0) {
1205 perror("ftp: socket");
1206 if (tmpno)
1207 sendport = 1;
1208 return (1);
1209 }
1210 if (!sendport)
1211 if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
1212 perror("ftp: setsockopt (reuse address)");
1213 goto bad;
1214 }
1215 if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
1216 perror("ftp: bind");
1217 goto bad;
1218 }
1219 if (options & SO_DEBUG &&
1220 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
1221 perror("ftp: setsockopt (ignored)");
1222 len = sizeof (data_addr);
1223 if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
1224 perror("ftp: getsockname");
1225 goto bad;
1226 }
1227 if (listen(data, 1) < 0)
1228 perror("ftp: listen");
1229 if (sendport) {
1230 a = (char *)&data_addr.sin_addr;
1231 p = (char *)&data_addr.sin_port;
1232 #define UC(b) (((int)b)&0xff)
1233 result =
1234 command("PORT %d,%d,%d,%d,%d,%d",
1235 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
1236 UC(p[0]), UC(p[1]));
1237 if (result == ERROR && sendport == -1) {
1238 sendport = 0;
1239 tmpno = 1;
1240 goto noport;
1241 }
1242 return (result != COMPLETE);
1243 }
1244 if (tmpno)
1245 sendport = 1;
1246 return (0);
1247 bad:
1248 (void) fflush(stdout);
1249 (void) close(data), data = -1;
1250 if (tmpno)
1251 sendport = 1;
1252 return (1);
1253 }
1254
1255 int dataconn(const char *mode)
1256 {
1257 struct sockaddr_in from;
1258 int s, fromlen = sizeof (from);
1259
1260 if (passivemode)
1261 return (data);
1262
1263 s = accept(data, (struct sockaddr *) &from, &fromlen);
1264 if (s < 0) {
1265 perror("ftp: accept");
1266 (void) closesocket(data), data = -1;
1267 return 0;
1268 }
1269 if(closesocket(data)) {
1270 int iret=WSAGetLastError ();
1271 fprintf(stdout,"Error closing socket(%d)\n",iret);
1272 (void) fflush(stdout);
1273 }
1274
1275 data = s;
1276 return (data);
1277 }
1278
1279 void ptransfer(direction, bytes, t0, t1)
1280 const char *direction;
1281 long bytes;
1282 struct timeval *t0, *t1;
1283 {
1284 struct timeval td;
1285 double s, bs;
1286
1287 if (verbose) {
1288 tvsub(&td, t1, t0);
1289 s = td.tv_sec + (td.tv_usec / 1000000.);
1290 #define nz(x) ((x) == 0 ? 1 : (x))
1291 bs = bytes / nz(s);
1292 printf("%ld bytes %s in %.1f seconds (%.0f Kbytes/s)\n",
1293 bytes, direction, s, bs / 1024.);
1294 (void) fflush(stdout);
1295 }
1296 }
1297
1298 /*tvadd(tsum, t0)
1299 struct timeval *tsum, *t0;
1300 {
1301
1302 tsum->tv_sec += t0->tv_sec;
1303 tsum->tv_usec += t0->tv_usec;
1304 if (tsum->tv_usec > 1000000)
1305 tsum->tv_sec++, tsum->tv_usec -= 1000000;
1306 } */
1307
1308 void tvsub(tdiff, t1, t0)
1309 struct timeval *tdiff, *t1, *t0;
1310 {
1311
1312 tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
1313 tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
1314 if (tdiff->tv_usec < 0)
1315 tdiff->tv_sec--, tdiff->tv_usec += 1000000;
1316 }
1317
1318 void psabort(int flag)
1319 {
1320 extern int abrtflag;
1321
1322 abrtflag++;
1323 }
1324
1325 void pswitch(int flag)
1326 {
1327 extern int proxy, abrtflag;
1328 Sig_t oldintr;
1329 static struct comvars {
1330 int connect;
1331 char name[MAXHOSTNAMELEN];
1332 struct sockaddr_in mctl;
1333 struct sockaddr_in hctl;
1334 SOCKET in;
1335 SOCKET out;
1336 int tpe;
1337 int cpnd;
1338 int sunqe;
1339 int runqe;
1340 int mcse;
1341 int ntflg;
1342 char nti[17];
1343 char nto[17];
1344 int mapflg;
1345 char mi[MAXPATHLEN];
1346 char mo[MAXPATHLEN];
1347 } proxstruct, tmpstruct;
1348 struct comvars *ip, *op;
1349
1350 abrtflag = 0;
1351 oldintr = signal(SIGINT, psabort);
1352 if (flag) {
1353 if (proxy)
1354 return;
1355 ip = &tmpstruct;
1356 op = &proxstruct;
1357 proxy++;
1358 }
1359 else {
1360 if (!proxy)
1361 return;
1362 ip = &proxstruct;
1363 op = &tmpstruct;
1364 proxy = 0;
1365 }
1366 ip->connect = connected;
1367 connected = op->connect;
1368 if (hostname) {
1369 (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
1370 ip->name[strlen(ip->name)] = '\0';
1371 } else
1372 ip->name[0] = 0;
1373 hostname = op->name;
1374 ip->hctl = hisctladdr;
1375 hisctladdr = op->hctl;
1376 ip->mctl = myctladdr;
1377 myctladdr = op->mctl;
1378 ip->in = cin;
1379 cin = op->in;
1380 ip->out = cout;
1381 cout = op->out;
1382 ip->tpe = type;
1383 type = op->tpe;
1384 if (!type)
1385 type = 1;
1386 ip->cpnd = cpend;
1387 cpend = op->cpnd;
1388 ip->sunqe = sunique;
1389 sunique = op->sunqe;
1390 ip->runqe = runique;
1391 runique = op->runqe;
1392 ip->mcse = mcase;
1393 mcase = op->mcse;
1394 ip->ntflg = ntflag;
1395 ntflag = op->ntflg;
1396 (void) strncpy(ip->nti, ntin, 16);
1397 (ip->nti)[strlen(ip->nti)] = '\0';
1398 (void) strcpy(ntin, op->nti);
1399 (void) strncpy(ip->nto, ntout, 16);
1400 (ip->nto)[strlen(ip->nto)] = '\0';
1401 (void) strcpy(ntout, op->nto);
1402 ip->mapflg = mapflag;
1403 mapflag = op->mapflg;
1404 (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
1405 (ip->mi)[strlen(ip->mi)] = '\0';
1406 (void) strcpy(mapin, op->mi);
1407 (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
1408 (ip->mo)[strlen(ip->mo)] = '\0';
1409 (void) strcpy(mapout, op->mo);
1410 // (void) signal(SIGINT, oldintr);
1411 if (abrtflag) {
1412 abrtflag = 0;
1413 (*oldintr)(1);
1414 }
1415 }
1416
1417 jmp_buf ptabort;
1418 int ptabflg;
1419
1420 #if 0
1421 void
1422 abortpt()
1423 {
1424 printf("\n");
1425 (void) fflush(stdout);
1426 ptabflg++;
1427 mflag = 0;
1428 abrtflag = 0;
1429 longjmp(ptabort, 1);
1430 }
1431 #endif
1432
1433 void proxtrans(cmd, local, remote)
1434 const char *cmd, *local, *remote;
1435 {
1436 // void (*oldintr)(int);
1437 int tmptype, oldtype = 0, secndflag = 0, nfnd;
1438 extern jmp_buf ptabort;
1439 const char *cmd2;
1440 // struct
1441 fd_set mask;
1442
1443 if (strcmp(cmd, "RETR"))
1444 cmd2 = "RETR";
1445 else
1446 cmd2 = runique ? "STOU" : "STOR";
1447 if (command("PASV") != COMPLETE) {
1448 printf("proxy server does not support third part transfers.\n");
1449 (void) fflush(stdout);
1450 return;
1451 }
1452 tmptype = type;
1453 pswitch(0);
1454 if (!connected) {
1455 printf("No primary connection\n");
1456 (void) fflush(stdout);
1457 pswitch(1);
1458 code = -1;
1459 return;
1460 }
1461 if (type != tmptype) {
1462 oldtype = type;
1463 switch (tmptype) {
1464 case TYPE_A:
1465 setascii();
1466 break;
1467 case TYPE_I:
1468 setbinary();
1469 break;
1470 case TYPE_E:
1471 setebcdic();
1472 break;
1473 case TYPE_L:
1474 settenex();
1475 break;
1476 }
1477 }
1478 if (command("PORT %s", pasv) != COMPLETE) {
1479 switch (oldtype) {
1480 case 0:
1481 break;
1482 case TYPE_A:
1483 setascii();
1484 break;
1485 case TYPE_I:
1486 setbinary();
1487 break;
1488 case TYPE_E:
1489 setebcdic();
1490 break;
1491 case TYPE_L:
1492 settenex();
1493 break;
1494 }
1495 pswitch(1);
1496 return;
1497 }
1498 if (setjmp(ptabort))
1499 goto abort;
1500 null();// oldintr = signal(SIGINT, abortpt);
1501 if (command("%s %s", cmd, remote) != PRELIM) {
1502 null();// (void) signal(SIGINT, oldintr);
1503 switch (oldtype) {
1504 case 0:
1505 break;
1506 case TYPE_A:
1507 setascii();
1508 break;
1509 case TYPE_I:
1510 setbinary();
1511 break;
1512 case TYPE_E:
1513 setebcdic();
1514 break;
1515 case TYPE_L:
1516 settenex();
1517 break;
1518 }
1519 pswitch(1);
1520 return;
1521 }
1522 sleep(2);
1523 pswitch(1);
1524 secndflag++;
1525 if (command("%s %s", cmd2, local) != PRELIM)
1526 goto abort;
1527 ptflag++;
1528 (void) getreply(0);
1529 pswitch(0);
1530 (void) getreply(0);
1531 null();// (void) signal(SIGINT, oldintr);
1532 switch (oldtype) {
1533 case 0:
1534 break;
1535 case TYPE_A:
1536 setascii();
1537 break;
1538 case TYPE_I:
1539 setbinary();
1540 break;
1541 case TYPE_E:
1542 setebcdic();
1543 break;
1544 case TYPE_L:
1545 settenex();
1546 break;
1547 }
1548 pswitch(1);
1549 ptflag = 0;
1550 printf("local: %s remote: %s\n", local, remote);
1551 (void) fflush(stdout);
1552 return;
1553 abort:
1554 null();// (void) signal(SIGINT, SIG_IGN);
1555 ptflag = 0;
1556 if (strcmp(cmd, "RETR") && !proxy)
1557 pswitch(1);
1558 else if (!strcmp(cmd, "RETR") && proxy)
1559 pswitch(0);
1560 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
1561 if (command("%s %s", cmd2, local) != PRELIM) {
1562 pswitch(0);
1563 switch (oldtype) {
1564 case 0:
1565 break;
1566 case TYPE_A:
1567 setascii();
1568 break;
1569 case TYPE_I:
1570 setbinary();
1571 break;
1572 case TYPE_E:
1573 setebcdic();
1574 break;
1575 case TYPE_L:
1576 settenex();
1577 break;
1578 }
1579 if (cpend) {
1580 char msg[2];
1581
1582 fprintfSocket(cout,"%c%c",IAC,IP);
1583 *msg = (char) IAC;
1584 *(msg+1) = (char) DM;
1585 if (send(cout,msg,2,MSG_OOB) != 2)
1586 perror("abort");
1587 fprintfSocket(cout,"ABOR\r\n");
1588 FD_ZERO(&mask);
1589 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this
1590 if ((nfnd = empty(&mask,10)) <= 0) {
1591 if (nfnd < 0) {
1592 perror("abort");
1593 }
1594 if (ptabflg)
1595 code = -1;
1596 lostpeer();
1597 }
1598 (void) getreply(0);
1599 (void) getreply(0);
1600 }
1601 }
1602 pswitch(1);
1603 if (ptabflg)
1604 code = -1;
1605 null();// (void) signal(SIGINT, oldintr);
1606 return;
1607 }
1608 if (cpend) {
1609 char msg[2];
1610
1611 fprintfSocket(cout,"%c%c",IAC,IP);
1612 *msg = (char)IAC;
1613 *(msg+1) = (char)DM;
1614 if (send(cout,msg,2,MSG_OOB) != 2)
1615 perror("abort");
1616 fprintfSocket(cout,"ABOR\r\n");
1617 FD_ZERO(&mask);
1618 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this...
1619 if ((nfnd = empty(&mask,10)) <= 0) {
1620 if (nfnd < 0) {
1621 perror("abort");
1622 }
1623 if (ptabflg)
1624 code = -1;
1625 lostpeer();
1626 }
1627 (void) getreply(0);
1628 (void) getreply(0);
1629 }
1630 pswitch(!proxy);
1631 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
1632 if (command("%s %s", cmd2, local) != PRELIM) {
1633 pswitch(0);
1634 switch (oldtype) {
1635 case 0:
1636 break;
1637 case TYPE_A:
1638 setascii();
1639 break;
1640 case TYPE_I:
1641 setbinary();
1642 break;
1643 case TYPE_E:
1644 setebcdic();
1645 break;
1646 case TYPE_L:
1647 settenex();
1648 break;
1649 }
1650 if (cpend) {
1651 char msg[2];
1652
1653 fprintfSocket(cout,"%c%c",IAC,IP);
1654 *msg = (char)IAC;
1655 *(msg+1) = (char)DM;
1656 if (send(cout,msg,2,MSG_OOB) != 2)
1657 perror("abort");
1658 fprintfSocket(cout,"ABOR\r\n");
1659 FD_ZERO(&mask);
1660 // FD_SET(fileno(cin), &mask); // Chris:
1661 if ((nfnd = empty(&mask,10)) <= 0) {
1662 if (nfnd < 0) {
1663 perror("abort");
1664 }
1665 if (ptabflg)
1666 code = -1;
1667 lostpeer();
1668 }
1669 (void) getreply(0);
1670 (void) getreply(0);
1671 }
1672 pswitch(1);
1673 if (ptabflg)
1674 code = -1;
1675 null();// (void) signal(SIGINT, oldintr);
1676 return;
1677 }
1678 }
1679 if (cpend) {
1680 char msg[2];
1681
1682 fprintfSocket(cout,"%c%c",IAC,IP);
1683 *msg = (char)IAC;
1684 *(msg+1) = (char)DM;
1685 if (send(cout,msg,2,MSG_OOB) != 2)
1686 perror("abort");
1687 fprintfSocket(cout,"ABOR\r\n");
1688 FD_ZERO(&mask);
1689 // FD_SET(fileno(cin), &mask); // Chris:
1690 if ((nfnd = empty(&mask,10)) <= 0) {
1691 if (nfnd < 0) {
1692 perror("abort");
1693 }
1694 if (ptabflg)
1695 code = -1;
1696 lostpeer();
1697 }
1698 (void) getreply(0);
1699 (void) getreply(0);
1700 }
1701 pswitch(!proxy);
1702 if (cpend) {
1703 FD_ZERO(&mask);
1704 // FD_SET(fileno(cin), &mask); // Chris:
1705 if ((nfnd = empty(&mask,10)) <= 0) {
1706 if (nfnd < 0) {
1707 perror("abort");
1708 }
1709 if (ptabflg)
1710 code = -1;
1711 lostpeer();
1712 }
1713 (void) getreply(0);
1714 (void) getreply(0);
1715 }
1716 if (proxy)
1717 pswitch(0);
1718 switch (oldtype) {
1719 case 0:
1720 break;
1721 case TYPE_A:
1722 setascii();
1723 break;
1724 case TYPE_I:
1725 setbinary();
1726 break;
1727 case TYPE_E:
1728 setebcdic();
1729 break;
1730 case TYPE_L:
1731 settenex();
1732 break;
1733 }
1734 pswitch(1);
1735 if (ptabflg)
1736 code = -1;
1737 null();// (void) signal(SIGINT, oldintr);
1738 }
1739
1740 void reset()
1741 {
1742 // struct
1743 fd_set mask;
1744 int nfnd = 1;
1745
1746 FD_ZERO(&mask);
1747 while (nfnd > 0) {
1748 // FD_SET(fileno(cin), &mask); // Chris
1749 if ((nfnd = empty(&mask,0)) < 0) {
1750 perror("reset");
1751 code = -1;
1752 lostpeer();
1753 }
1754 else if (nfnd) {
1755 (void) getreply(0);
1756 }
1757 }
1758 }
1759
1760 #if 0
1761 char *
1762 gunique(local)
1763 char *local;
1764 {
1765 static char new[MAXPATHLEN];
1766 char *cp = rindex(local, '/');
1767 int d, count=0;
1768 char ext = '1';
1769
1770 if (cp)
1771 *cp = '\0';
1772 d = access(cp ? local : ".", 2);
1773 if (cp)
1774 *cp = '/';
1775 if (d < 0) {
1776 perror(local);
1777 return((char *) 0);
1778 }
1779 (void) strcpy(new, local);
1780 cp = new + strlen(new);
1781 *cp++ = '.';
1782 while (!d) {
1783 if (++count == 100) {
1784 printf("runique: can't find unique file name.\n");
1785 (void) fflush(stdout);
1786 return((char *) 0);
1787 }
1788 *cp++ = ext;
1789 *cp = '\0';
1790 if (ext == '9')
1791 ext = '0';
1792 else
1793 ext++;
1794 if ((d = access(new, 0)) < 0)
1795 break;
1796 if (ext != '0')
1797 cp--;
1798 else if (*(cp - 2) == '.')
1799 *(cp - 1) = '1';
1800 else {
1801 *(cp - 2) = *(cp - 2) + 1;
1802 cp--;
1803 }
1804 }
1805 return(new);
1806 }
1807 #endif
1808
1809 int null(void)
1810 {
1811 return 0;
1812 }