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