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