fixed some signed/unsigned comparison warnings with -Wsign-compare
[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 != (unsigned long)-1) {
123 hisctladdr.sin_family = AF_INET;
124 (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));
125 } else {
126 hp = gethostbyname(host);
127 if (hp == NULL) {
128 fprintf(stderr, "ftp: %s: ", host);
129 herror((char *)NULL);
130 code = -1;
131 return((char *) 0);
132 }
133 hisctladdr.sin_family = hp->h_addrtype;
134 bcopy(hp->h_addr_list[0],
135 (caddr_t)&hisctladdr.sin_addr, hp->h_length);
136 (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
137 }
138 hostname = hostnamebuf;
139 s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
140 if (s == INVALID_SOCKET) {
141 perror("ftp: socket");
142 code = -1;
143 return (0);
144 }
145 hisctladdr.sin_port = port;
146 while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
147 if (hp && hp->h_addr_list[1]) {
148 int oerrno = errno;
149
150 fprintf(stderr, "ftp: connect to address %s: ",
151 inet_ntoa(hisctladdr.sin_addr));
152 errno = oerrno;
153 perror((char *) 0);
154 hp->h_addr_list++;
155 bcopy(hp->h_addr_list[0],
156 (caddr_t)&hisctladdr.sin_addr, hp->h_length);
157 fprintf(stdout, "Trying %s...\n",
158 inet_ntoa(hisctladdr.sin_addr));
159 (void) fflush(stdout);
160 (void) close(s);
161 s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
162 if (s < 0) {
163 perror("ftp: socket");
164 code = -1;
165 return (0);
166 }
167 continue;
168 }
169 perror("ftp: connect");
170 code = -1;
171 goto bad;
172 }
173 len = sizeof (myctladdr);
174 if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
175 perror("ftp: getsockname");
176 code = -1;
177 goto bad;
178 }
179 cin = cout = s;
180 if (verbose) {
181 printf("Connected to %s.\n", hostname);
182 (void) fflush(stdout);
183 }
184 if (getreply(0) > 2) { /* read startup message from server */
185 closesocket(cin);
186 code = -1;
187 goto bad;
188 }
189 #ifdef SO_OOBINLINE
190 {
191 int on = 1;
192
193 if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (const char *) &on, sizeof(on))
194 < 0 && debug) {
195 perror("ftp: setsockopt");
196 }
197 }
198 #endif //SO_OOBINLINE
199
200 return (hostname);
201 bad:
202 (void) close(s);
203 return ((char *)0);
204 }
205
206 int login(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 int
324 getreply(expecteof)
325 int expecteof;
326 {
327 register int c, n;
328 register int dig;
329 register char *cp;
330 int originalcode = 0, continuation = 0;
331 void (*oldintr)(int), cmdabort(int);
332 int pflag = 0;
333 char *pt = pasv;
334
335 oldintr = signal(SIGINT,cmdabort);
336 for (;;) {
337 dig = n = code = 0;
338 cp = reply_string;
339 while ((c = fgetcSocket(cin)) != '\n') {
340 if (c == IAC) { /* handle telnet commands */
341 switch (c = fgetcSocket(cin)) {
342 case WILL:
343 case WONT:
344 c = fgetcSocket(cin);
345 fprintfSocket(cout, "%c%c%c",IAC,DONT,c);
346 break;
347 case DO:
348 case DONT:
349 c = fgetcSocket(cin);
350 fprintfSocket(cout, "%c%c%c",IAC,WONT,c);
351 break;
352 default:
353 break;
354 }
355 continue;
356 }
357 dig++;
358 if (c == EOF) {
359 if (expecteof) {
360 // (void) signal(SIGINT,oldintr);
361 code = 221;
362 return (0);
363 }
364 lostpeer();
365 if (verbose) {
366 printf("421 Service not available, remote server has closed connection\n");
367 (void) fflush(stdout);
368 }
369 code = 421;
370 return(4);
371 }
372 if (c != '\r' && (verbose > 0 ||
373 (verbose > -1 && n == '5' && dig > 4))) {
374 if (proxflag &&
375 ((dig == 1 || dig == 5) && verbose == 0))
376 printf("%s:",hostname);
377 (void) putchar(c);
378 (void) fflush(stdout);
379 }
380 if (dig < 4 && isdigit(c))
381 code = code * 10 + (c - '0');
382 if (!pflag && code == 227)
383 pflag = 1;
384 if (dig > 4 && pflag == 1 && isdigit(c))
385 pflag = 2;
386 if (pflag == 2) {
387 if (c != '\r' && c != ')')
388 *pt++ = c;
389 else {
390 *pt = '\0';
391 pflag = 3;
392 }
393 }
394 if (dig == 4 && c == '-') {
395 if (continuation)
396 code = 0;
397 continuation++;
398 }
399 if (n == 0)
400 n = c;
401 if (cp < &reply_string[sizeof(reply_string) - 1])
402 *cp++ = c;
403 }
404 if (verbose > 0 || (verbose > -1 && n == '5')) {
405 (void) putchar(c);
406 (void) fflush (stdout);
407 }
408 if (continuation && code != originalcode) {
409 if (originalcode == 0)
410 originalcode = code;
411 continue;
412 }
413 *cp = '\0';
414 if (n != '1')
415 cpend = 0;
416 (void) signal(SIGINT,oldintr);
417 if (code == 421 || originalcode == 421)
418 lostpeer();
419 if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
420 (*oldintr)(SIGINT);
421 return (n - '0');
422 }
423 }
424
425 int
426 empty(mask, sec)
427 struct fd_set *mask;
428 int sec;
429 {
430 struct timeval t;
431
432 t.tv_sec = (long) sec;
433 t.tv_usec = 0;
434 return(select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t));
435 }
436
437 jmp_buf sendabort;
438
439 void abortsend()
440 {
441
442 mflag = 0;
443 abrtflag = 0;
444 printf("\nsend aborted\n");
445 (void) fflush(stdout);
446 longjmp(sendabort, 1);
447 }
448
449 #define HASHBYTES 1024
450
451 void sendrequest(char *cmd, char *local, char *remote, int printnames)
452 {
453 FILE *fin;
454 int dout = 0;
455 int (*closefunc)(), _pclose(), fclose();
456 sig_t (*oldintr)(), (*oldintp)();
457 void abortsend();
458 char buf[BUFSIZ], *bufp;
459 long bytes = 0, hashbytes = HASHBYTES;
460 register int c, d;
461 struct stat st;
462 struct timeval start, stop;
463 char *mode;
464
465 if (verbose && printnames) {
466 if (local && *local != '-')
467 printf("local: %s ", local);
468 if (remote)
469 printf("remote: %s\n", remote);
470 (void) fflush(stdout);
471 }
472 if (proxy) {
473 proxtrans(cmd, local, remote);
474 return;
475 }
476 closefunc = NULL;
477 oldintr = NULL;
478 oldintp = NULL;
479 mode = "w";
480 if (setjmp(sendabort)) {
481 while (cpend) {
482 (void) getreply(0);
483 }
484 if (data >= 0) {
485 (void) close(data);
486 data = -1;
487 }
488 if (oldintr)
489 null();// (void) signal(SIGINT,oldintr);
490 if (oldintp)
491 null();// (void) signal(SIGPIPE,oldintp);
492 code = -1;
493 return;
494 }
495 null();// oldintr = signal(SIGINT, abortsend);
496 if (strcmp(local, "-") == 0)
497 fin = stdin;
498 else if (*local == '|') {
499 null();// oldintp = signal(SIGPIPE,SIG_IGN);
500 fin = _popen(local + 1, "r");
501 if (fin == NULL) {
502 perror(local + 1);
503 null();// (void) signal(SIGINT, oldintr);
504 null();// (void) signal(SIGPIPE, oldintp);
505 code = -1;
506 return;
507 }
508 closefunc = _pclose;
509 } else {
510 fin = fopen(local, "r");
511 if (fin == NULL) {
512 perror(local);
513 null();// (void) signal(SIGINT, oldintr);
514 code = -1;
515 return;
516 }
517 closefunc = fclose;
518 if (fstat(fileno(fin), &st) < 0 ||
519 (st.st_mode&S_IFMT) != S_IFREG) {
520 fprintf(stdout, "%s: not a plain file.\n", local);
521 (void) fflush(stdout);
522 null();// (void) signal(SIGINT, oldintr);
523 fclose(fin);
524 code = -1;
525 return;
526 }
527 }
528 if (initconn()) {
529 null();// (void) signal(SIGINT, oldintr);
530 if (oldintp)
531 null();// (void) signal(SIGPIPE, oldintp);
532 code = -1;
533 if (closefunc != NULL)
534 (*closefunc)(fin);
535 return;
536 }
537 if (setjmp(sendabort))
538 goto abort;
539
540 if (restart_point &&
541 (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
542 if (fseek(fin, (long) restart_point, 0) < 0) {
543 perror(local);
544 restart_point = 0;
545 if (closefunc != NULL)
546 (*closefunc)(fin);
547 return;
548 }
549 if (command("REST %ld", (long) restart_point)
550 != CONTINUE) {
551 restart_point = 0;
552 if (closefunc != NULL)
553 (*closefunc)(fin);
554 return;
555 }
556 restart_point = 0;
557 mode = "r+w";
558 }
559 if (remote) {
560 if (command("%s %s", cmd, remote) != PRELIM) {
561 null();// (void) signal(SIGINT, oldintr);
562 if (oldintp)
563 null();// (void) signal(SIGPIPE, oldintp);
564 if (closefunc != NULL)
565 (*closefunc)(fin);
566 return;
567 }
568 } else
569 if (command("%s", cmd) != PRELIM) {
570 null();// (void) signal(SIGINT, oldintr);
571 if (oldintp)
572 null();// (void) signal(SIGPIPE, oldintp);
573 if (closefunc != NULL)
574 (*closefunc)(fin);
575 return;
576 }
577 dout = dataconn(mode);
578 if (dout == (int)NULL)
579 goto abort;
580 (void) gettimeofday(&start, (struct timezone *)0);
581 null();// oldintp = signal(SIGPIPE, SIG_IGN);
582 switch (type) {
583
584 case TYPE_I:
585 case TYPE_L:
586 errno = d = 0;
587 while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
588 bytes += c;
589 for (bufp = buf; c > 0; c -= d, bufp += d)
590 if ((d = send(dout, bufp, c, 0)) <= 0)
591 break;
592 if (hash) {
593 while (bytes >= hashbytes) {
594 (void) putchar('#');
595 hashbytes += HASHBYTES;
596 }
597 (void) fflush(stdout);
598 }
599 }
600 if (hash && bytes > 0) {
601 if (bytes < HASHBYTES)
602 (void) putchar('#');
603 (void) putchar('\n');
604 (void) fflush(stdout);
605 }
606 if (c < 0)
607 perror(local);
608 if (d <= 0) {
609 if (d == 0)
610 fprintf(stderr, "netout: write returned 0?\n");
611 else if (errno != EPIPE)
612 perror("netout");
613 bytes = -1;
614 }
615 break;
616
617 case TYPE_A:
618 {
619 char buf[1024];
620 static int bufsize = 1024;
621 int ipos=0;
622
623 while ((c = getc(fin)) != EOF) {
624 if (c == '\n') {
625 while (hash && (bytes >= hashbytes)) {
626 (void) putchar('#');
627 (void) fflush(stdout);
628 hashbytes += HASHBYTES;
629 }
630 // Szurgot: The following code is unncessary on Win32.
631 // (void) fputcSocket(dout, '\r');
632 // bytes++;
633 }
634
635 if (ipos >= bufsize) {
636 fputSocket(dout,buf,ipos);
637 if(!hash) (void) putchar('.');
638 ipos=0;
639 }
640 buf[ipos]=c; ++ipos;
641 bytes++;
642 }
643 if (ipos) {
644 fputSocket(dout,buf,ipos);
645 ipos=0;
646 }
647 if (hash) {
648 if (bytes < hashbytes)
649 (void) putchar('#');
650 (void) putchar('\n');
651 (void) fflush(stdout);
652 }
653 else {
654 (void) putchar('.');
655 (void) putchar('\n');
656 (void) fflush(stdout);
657 }
658 if (ferror(fin))
659 perror(local);
660 // if (ferror(dout)) {
661 // if (errno != EPIPE)
662 // perror("netout");
663 // bytes = -1;
664 // }
665 break;
666 }
667 }
668 (void) gettimeofday(&stop, (struct timezone *)0);
669 if (closefunc != NULL)
670 (*closefunc)(fin);
671 if(closesocket(dout)) {
672 int iret=WSAGetLastError ();
673 fprintf(stdout,"Error closing socket(%d)\n",iret);
674 (void) fflush(stdout);
675 }
676 (void) getreply(0);
677 null();// (void) signal(SIGINT, oldintr);
678 if (oldintp)
679 null();// (void) signal(SIGPIPE, oldintp);
680 if (bytes > 0)
681 ptransfer("sent", bytes, &start, &stop);
682 return;
683 abort:
684 (void) gettimeofday(&stop, (struct timezone *)0);
685 null();// (void) signal(SIGINT, oldintr);
686 if (oldintp)
687 null();// (void) signal(SIGPIPE, oldintp);
688 if (!cpend) {
689 code = -1;
690 return;
691 }
692 if (data >= 0) {
693 (void) close(data);
694 data = -1;
695 }
696 if (dout)
697 if(closesocket(dout)) {
698 int iret=WSAGetLastError ();
699 fprintf(stdout,"Error closing socket(%d)\n",iret);
700 (void) fflush(stdout);
701 }
702
703 (void) getreply(0);
704 code = -1;
705 if (closefunc != NULL && fin != NULL)
706 (*closefunc)(fin);
707 if (bytes > 0)
708 ptransfer("sent", bytes, &start, &stop);
709 }
710
711 jmp_buf recvabort;
712
713
714 void abortrecv()
715 {
716
717 mflag = 0;
718 abrtflag = 0;
719 printf("\n");
720 (void) fflush(stdout);
721 longjmp(recvabort, 1);
722 }
723
724 void recvrequest(char *cmd, char *local, char *remote, char *mode,
725 int printnames)
726 {
727 FILE *fout;
728 int din = 0;
729 int (*closefunc)(), _pclose(), fclose();
730 void (*oldintr)(int), (*oldintp)(int);
731 void abortrecv();
732 int oldverbose, oldtype = 0, is_retr, tcrflag, nfnd, bare_lfs = 0;
733 char *gunique(), msg;
734 // static char *buf; // Szurgot: Shouldn't this go SOMEWHERE?
735 char buf[1024];
736 static int bufsize = 1024;
737 long bytes = 0, hashbytes = HASHBYTES;
738 // struct
739 fd_set mask;
740 register int c, d;
741 struct timeval start, stop;
742 // struct stat st;
743 extern void *malloc();
744
745 is_retr = strcmp(cmd, "RETR") == 0;
746 if (is_retr && verbose && printnames) {
747 if (local && *local != '-')
748 printf("local: %s ", local);
749 if (remote)
750 printf("remote: %s\n", remote);
751 (void) fflush(stdout);
752 }
753 if (proxy && is_retr) {
754 proxtrans(cmd, local, remote);
755 return;
756 }
757 closefunc = NULL;
758 oldintr = NULL;
759 oldintp = NULL;
760 tcrflag = !crflag && is_retr;
761 if (setjmp(recvabort)) {
762 while (cpend) {
763 (void) getreply(0);
764 }
765 if (data >= 0) {
766 (void) close(data);
767 data = -1;
768 }
769 if (oldintr)
770 null();// (void) signal(SIGINT, oldintr);
771 code = -1;
772 return;
773 }
774 null();// oldintr = signal(SIGINT, abortrecv);
775 if (strcmp(local, "-") && *local != '|') {
776 #ifndef __WIN32__
777 // This whole thing is a problem... access Won't work on non-existent files
778 if (access(local, 2) < 0) {
779 char *dir = rindex(local, '/');
780
781 if (errno != ENOENT && errno != EACCES) {
782 perror(local);
783 (void) signal(SIGINT, oldintr);
784 code = -1;
785 return;
786 }
787 if (dir != NULL)
788 *dir = 0;
789 d = access(dir ? local : ".", 2);
790 if (dir != NULL)
791 *dir = '/';
792 if (d < 0) {
793 perror(local);
794 (void) signal(SIGINT, oldintr);
795 code = -1;
796 return;
797 }
798 if (!runique && errno == EACCES &&
799 chmod(local, 0600) < 0) {
800 perror(local);
801 (void) signal(SIGINT, oldintr);
802 code = -1;
803 return;
804 }
805 if (runique && errno == EACCES &&
806 (local = gunique(local)) == NULL) {
807 (void) signal(SIGINT, oldintr);
808 code = -1;
809 return;
810 }
811 }
812 else if (runique && (local = gunique(local)) == NULL) {
813 (void) signal(SIGINT, oldintr);
814 code = -1;
815 return;
816 }
817 #endif
818 }
819 if (initconn()) {
820 null();// (void) signal(SIGINT, oldintr);
821 code = -1;
822 return;
823 }
824 if (setjmp(recvabort))
825 goto abort;
826 if (!is_retr) {
827 if (type != TYPE_A && (allbinary == 0 || type != TYPE_I)) {
828 oldtype = type;
829 oldverbose = verbose;
830 if (!debug)
831 verbose = 0;
832 setascii();
833 verbose = oldverbose;
834 }
835 } else if (restart_point) {
836 if (command("REST %ld", (long) restart_point) != CONTINUE)
837 return;
838 }
839 if (remote) {
840 if (command("%s %s", cmd, remote) != PRELIM) {
841 null();// (void) signal(SIGINT, oldintr);
842 if (oldtype) {
843 if (!debug)
844 verbose = 0;
845 switch (oldtype) {
846 case TYPE_I:
847 setbinary();
848 break;
849 case TYPE_E:
850 setebcdic();
851 break;
852 case TYPE_L:
853 settenex();
854 break;
855 }
856 verbose = oldverbose;
857 }
858 return;
859 }
860 } else {
861 if (command("%s", cmd) != PRELIM) {
862 null();// (void) signal(SIGINT, oldintr);
863 if (oldtype) {
864 if (!debug)
865 verbose = 0;
866 switch (oldtype) {
867 case TYPE_I:
868 setbinary();
869 break;
870 case TYPE_E:
871 setebcdic();
872 break;
873 case TYPE_L:
874 settenex();
875 break;
876 }
877 verbose = oldverbose;
878 }
879 return;
880 }
881 }
882 din = dataconn("r");
883 if (din == (int)NULL)
884 goto abort;
885 if (strcmp(local, "-") == 0)
886 fout = stdout;
887 else if (*local == '|') {
888 null();// oldintp = signal(SIGPIPE, SIG_IGN);
889 fout = _popen(local + 1, "w");
890 if (fout == NULL) {
891 perror(local+1);
892 goto abort;
893 }
894 closefunc = _pclose;
895 } else {
896 fout = fopen(local, mode);
897 if (fout == NULL) {
898 perror(local);
899 goto abort;
900 }
901 closefunc = fclose;
902 }
903 (void) gettimeofday(&start, (struct timezone *)0);
904 switch (type) {
905
906 case TYPE_I:
907 case TYPE_L:
908 if (restart_point &&
909 lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
910 perror(local);
911 if (closefunc != NULL)
912 (*closefunc)(fout);
913 return;
914 }
915 errno = d = 0;
916 // while ((c = recv(din, buf, bufsize, 1)) > 0) {
917 // if ((d = write(fileno(fout), buf, c)) != c)
918 // if ((d = write(fileno(fout), buf, c)) != c)
919 // break;
920 while ((c = recv(din, buf, bufsize, 0)) > 0) {
921 write(fileno(fout), buf, c);
922 bytes += c;
923 if (hash) {
924 while (bytes >= hashbytes) {
925 (void) putchar('#');
926 hashbytes += HASHBYTES;
927 }
928 (void) fflush(stdout);
929 }
930 }
931 if (hash && bytes > 0) {
932 if (bytes < HASHBYTES)
933 (void) putchar('#');
934 (void) putchar('\n');
935 (void) fflush(stdout);
936 }
937 // if (c < 0) {
938 // if (errno != EPIPE)
939 // perror("netin");
940 // bytes = -1;
941 // }
942 // if (d < c) {
943 // if (d < 0)
944 // perror(local);
945 // else
946 // fprintf(stderr, "%s: short write\n", local);
947 // }
948 break;
949
950 case TYPE_A:
951 if (restart_point) {
952 register int i, n, c;
953
954 if (fseek(fout, 0L, L_SET) < 0)
955 goto done;
956 n = restart_point;
957 i = 0;
958 while (i++ < n) {
959 if ((c=getc(fout)) == EOF)
960 goto done;
961 if (c == '\n')
962 i++;
963 }
964 if (fseek(fout, 0L, L_INCR) < 0) {
965 done:
966 perror(local);
967 if (closefunc != NULL)
968 (*closefunc)(fout);
969 return;
970 }
971 }
972 while ((c = fgetcSocket(din)) != EOF) {
973 if (c == '\n')
974 bare_lfs++;
975 while (c == '\r') {
976 while (hash && (bytes >= hashbytes)) {
977 (void) putchar('#');
978 (void) fflush(stdout);
979 hashbytes += HASHBYTES;
980 }
981 bytes++;
982 if ((c = fgetcSocket(din)) != '\n' || tcrflag) {
983 if (ferror(fout))
984 goto break2;
985 (void) putc('\r', fout);
986 if (c == '\0') {
987 bytes++;
988 goto contin2;
989 }
990 if (c == EOF)
991 goto contin2;
992 }
993 }
994 (void) putc(c, fout);
995 bytes++;
996 contin2: ;
997 }
998 break2:
999 if (bare_lfs) {
1000 printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
1001 printf("File may not have transferred correctly.\n");
1002 (void) fflush(stdout);
1003 }
1004 if (hash) {
1005 if (bytes < hashbytes)
1006 (void) putchar('#');
1007 (void) putchar('\n');
1008 (void) fflush(stdout);
1009 }
1010 // if (ferror(din)) {
1011 // if (errno != EPIPE)
1012 // perror("netin");
1013 // bytes = -1;
1014 // }
1015 if (ferror(fout))
1016 perror(local);
1017 break;
1018 }
1019 if (closefunc != NULL)
1020 (*closefunc)(fout);
1021 null();// (void) signal(SIGINT, oldintr);
1022 if (oldintp)
1023 null();// (void) signal(SIGPIPE, oldintp);
1024 (void) gettimeofday(&stop, (struct timezone *)0);
1025 if(closesocket(din)) {
1026 int iret=WSAGetLastError ();
1027 fprintf(stdout,"Error closing socket(%d)\n",iret);
1028 (void) fflush(stdout);
1029 }
1030
1031 (void) getreply(0);
1032 if (bytes > 0 && is_retr)
1033 ptransfer("received", bytes, &start, &stop);
1034 if (oldtype) {
1035 if (!debug)
1036 verbose = 0;
1037 switch (oldtype) {
1038 case TYPE_I:
1039 setbinary();
1040 break;
1041 case TYPE_E:
1042 setebcdic();
1043 break;
1044 case TYPE_L:
1045 settenex();
1046 break;
1047 }
1048 verbose = oldverbose;
1049 }
1050 return;
1051 abort:
1052
1053 /* abort using RFC959 recommended IP,SYNC sequence */
1054
1055 (void) gettimeofday(&stop, (struct timezone *)0);
1056 if (oldintp)
1057 null();// (void) signal(SIGPIPE, oldintr);
1058 null();// (void) signal(SIGINT,SIG_IGN);
1059 if (oldtype) {
1060 if (!debug)
1061 verbose = 0;
1062 switch (oldtype) {
1063 case TYPE_I:
1064 setbinary();
1065 break;
1066 case TYPE_E:
1067 setebcdic();
1068 break;
1069 case TYPE_L:
1070 settenex();
1071 break;
1072 }
1073 verbose = oldverbose;
1074 }
1075 if (!cpend) {
1076 code = -1;
1077 null();// (void) signal(SIGINT,oldintr);
1078 return;
1079 }
1080
1081 fprintfSocket(cout,"%c%c",IAC,IP);
1082 msg = (char)IAC;
1083 /* send IAC in urgent mode instead of DM because UNIX places oob mark */
1084 /* after urgent byte rather than before as now is protocol */
1085 if (send(cout,&msg,1,MSG_OOB) != 1) {
1086 perror("abort");
1087 }
1088 fprintfSocket(cout,"%cABOR\r\n",DM);
1089 FD_ZERO(&mask);
1090 FD_SET(cin, &mask); // Need to correct this
1091 if (din) {
1092 FD_SET(din, &mask); // Need to correct this
1093 }
1094 if ((nfnd = empty(&mask,10)) <= 0) {
1095 if (nfnd < 0) {
1096 perror("abort");
1097 }
1098 code = -1;
1099 lostpeer();
1100 }
1101 if (din && FD_ISSET(din, &mask)) {
1102 while ((c = recv(din, buf, bufsize, 0)) > 0)
1103 ;
1104 }
1105 if ((c = getreply(0)) == ERROR && code == 552) { /* needed for nic style abort */
1106 if (data >= 0) {
1107 (void) close(data);
1108 data = -1;
1109 }
1110 (void) getreply(0);
1111 }
1112 (void) getreply(0);
1113 code = -1;
1114 if (data >= 0) {
1115 (void) close(data);
1116 data = -1;
1117 }
1118 if (closefunc != NULL && fout != NULL)
1119 (*closefunc)(fout);
1120 if (din)
1121 if(closesocket(din)) {
1122 int iret=WSAGetLastError ();
1123 fprintf(stdout,"Error closing socket(%d)\n",iret);
1124 (void) fflush(stdout);
1125 }
1126
1127 if (bytes > 0)
1128 ptransfer("received", bytes, &start, &stop);
1129 null();// (void) signal(SIGINT,oldintr);
1130 }
1131
1132 /*
1133 * Need to start a listen on the data channel
1134 * before we send the command, otherwise the
1135 * server's connect may fail.
1136 */
1137 int sendport = -1;
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(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 (int) (NULL);
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 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 %.2g seconds (%.2g 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 void
1421 abortpt()
1422 {
1423 printf("\n");
1424 (void) fflush(stdout);
1425 ptabflg++;
1426 mflag = 0;
1427 abrtflag = 0;
1428 longjmp(ptabort, 1);
1429 }
1430
1431 void proxtrans(cmd, local, remote)
1432 char *cmd, *local, *remote;
1433 {
1434 // void (*oldintr)(int);
1435 //void abortpt(int);
1436 int tmptype, oldtype = 0, secndflag = 0, nfnd;
1437 extern jmp_buf ptabort;
1438 char *cmd2;
1439 // struct
1440 fd_set mask;
1441
1442 if (strcmp(cmd, "RETR"))
1443 cmd2 = "RETR";
1444 else
1445 cmd2 = runique ? "STOU" : "STOR";
1446 if (command("PASV") != COMPLETE) {
1447 printf("proxy server does not support third part transfers.\n");
1448 (void) fflush(stdout);
1449 return;
1450 }
1451 tmptype = type;
1452 pswitch(0);
1453 if (!connected) {
1454 printf("No primary connection\n");
1455 (void) fflush(stdout);
1456 pswitch(1);
1457 code = -1;
1458 return;
1459 }
1460 if (type != tmptype) {
1461 oldtype = type;
1462 switch (tmptype) {
1463 case TYPE_A:
1464 setascii();
1465 break;
1466 case TYPE_I:
1467 setbinary();
1468 break;
1469 case TYPE_E:
1470 setebcdic();
1471 break;
1472 case TYPE_L:
1473 settenex();
1474 break;
1475 }
1476 }
1477 if (command("PORT %s", pasv) != COMPLETE) {
1478 switch (oldtype) {
1479 case 0:
1480 break;
1481 case TYPE_A:
1482 setascii();
1483 break;
1484 case TYPE_I:
1485 setbinary();
1486 break;
1487 case TYPE_E:
1488 setebcdic();
1489 break;
1490 case TYPE_L:
1491 settenex();
1492 break;
1493 }
1494 pswitch(1);
1495 return;
1496 }
1497 if (setjmp(ptabort))
1498 goto abort;
1499 null();// oldintr = signal(SIGINT, abortpt);
1500 if (command("%s %s", cmd, remote) != PRELIM) {
1501 null();// (void) signal(SIGINT, oldintr);
1502 switch (oldtype) {
1503 case 0:
1504 break;
1505 case TYPE_A:
1506 setascii();
1507 break;
1508 case TYPE_I:
1509 setbinary();
1510 break;
1511 case TYPE_E:
1512 setebcdic();
1513 break;
1514 case TYPE_L:
1515 settenex();
1516 break;
1517 }
1518 pswitch(1);
1519 return;
1520 }
1521 sleep(2);
1522 pswitch(1);
1523 secndflag++;
1524 if (command("%s %s", cmd2, local) != PRELIM)
1525 goto abort;
1526 ptflag++;
1527 (void) getreply(0);
1528 pswitch(0);
1529 (void) getreply(0);
1530 null();// (void) signal(SIGINT, oldintr);
1531 switch (oldtype) {
1532 case 0:
1533 break;
1534 case TYPE_A:
1535 setascii();
1536 break;
1537 case TYPE_I:
1538 setbinary();
1539 break;
1540 case TYPE_E:
1541 setebcdic();
1542 break;
1543 case TYPE_L:
1544 settenex();
1545 break;
1546 }
1547 pswitch(1);
1548 ptflag = 0;
1549 printf("local: %s remote: %s\n", local, remote);
1550 (void) fflush(stdout);
1551 return;
1552 abort:
1553 null();// (void) signal(SIGINT, SIG_IGN);
1554 ptflag = 0;
1555 if (strcmp(cmd, "RETR") && !proxy)
1556 pswitch(1);
1557 else if (!strcmp(cmd, "RETR") && proxy)
1558 pswitch(0);
1559 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
1560 if (command("%s %s", cmd2, local) != PRELIM) {
1561 pswitch(0);
1562 switch (oldtype) {
1563 case 0:
1564 break;
1565 case TYPE_A:
1566 setascii();
1567 break;
1568 case TYPE_I:
1569 setbinary();
1570 break;
1571 case TYPE_E:
1572 setebcdic();
1573 break;
1574 case TYPE_L:
1575 settenex();
1576 break;
1577 }
1578 if (cpend) {
1579 char msg[2];
1580
1581 fprintfSocket(cout,"%c%c",IAC,IP);
1582 *msg = (char) IAC;
1583 *(msg+1) = (char) DM;
1584 if (send(cout,msg,2,MSG_OOB) != 2)
1585 perror("abort");
1586 fprintfSocket(cout,"ABOR\r\n");
1587 FD_ZERO(&mask);
1588 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this
1589 if ((nfnd = empty(&mask,10)) <= 0) {
1590 if (nfnd < 0) {
1591 perror("abort");
1592 }
1593 if (ptabflg)
1594 code = -1;
1595 lostpeer();
1596 }
1597 (void) getreply(0);
1598 (void) getreply(0);
1599 }
1600 }
1601 pswitch(1);
1602 if (ptabflg)
1603 code = -1;
1604 null();// (void) signal(SIGINT, oldintr);
1605 return;
1606 }
1607 if (cpend) {
1608 char msg[2];
1609
1610 fprintfSocket(cout,"%c%c",IAC,IP);
1611 *msg = (char)IAC;
1612 *(msg+1) = (char)DM;
1613 if (send(cout,msg,2,MSG_OOB) != 2)
1614 perror("abort");
1615 fprintfSocket(cout,"ABOR\r\n");
1616 FD_ZERO(&mask);
1617 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this...
1618 if ((nfnd = empty(&mask,10)) <= 0) {
1619 if (nfnd < 0) {
1620 perror("abort");
1621 }
1622 if (ptabflg)
1623 code = -1;
1624 lostpeer();
1625 }
1626 (void) getreply(0);
1627 (void) getreply(0);
1628 }
1629 pswitch(!proxy);
1630 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
1631 if (command("%s %s", cmd2, local) != PRELIM) {
1632 pswitch(0);
1633 switch (oldtype) {
1634 case 0:
1635 break;
1636 case TYPE_A:
1637 setascii();
1638 break;
1639 case TYPE_I:
1640 setbinary();
1641 break;
1642 case TYPE_E:
1643 setebcdic();
1644 break;
1645 case TYPE_L:
1646 settenex();
1647 break;
1648 }
1649 if (cpend) {
1650 char msg[2];
1651
1652 fprintfSocket(cout,"%c%c",IAC,IP);
1653 *msg = (char)IAC;
1654 *(msg+1) = (char)DM;
1655 if (send(cout,msg,2,MSG_OOB) != 2)
1656 perror("abort");
1657 fprintfSocket(cout,"ABOR\r\n");
1658 FD_ZERO(&mask);
1659 // FD_SET(fileno(cin), &mask); // Chris:
1660 if ((nfnd = empty(&mask,10)) <= 0) {
1661 if (nfnd < 0) {
1662 perror("abort");
1663 }
1664 if (ptabflg)
1665 code = -1;
1666 lostpeer();
1667 }
1668 (void) getreply(0);
1669 (void) getreply(0);
1670 }
1671 pswitch(1);
1672 if (ptabflg)
1673 code = -1;
1674 null();// (void) signal(SIGINT, oldintr);
1675 return;
1676 }
1677 }
1678 if (cpend) {
1679 char msg[2];
1680
1681 fprintfSocket(cout,"%c%c",IAC,IP);
1682 *msg = (char)IAC;
1683 *(msg+1) = (char)DM;
1684 if (send(cout,msg,2,MSG_OOB) != 2)
1685 perror("abort");
1686 fprintfSocket(cout,"ABOR\r\n");
1687 FD_ZERO(&mask);
1688 // FD_SET(fileno(cin), &mask); // Chris:
1689 if ((nfnd = empty(&mask,10)) <= 0) {
1690 if (nfnd < 0) {
1691 perror("abort");
1692 }
1693 if (ptabflg)
1694 code = -1;
1695 lostpeer();
1696 }
1697 (void) getreply(0);
1698 (void) getreply(0);
1699 }
1700 pswitch(!proxy);
1701 if (cpend) {
1702 FD_ZERO(&mask);
1703 // FD_SET(fileno(cin), &mask); // Chris:
1704 if ((nfnd = empty(&mask,10)) <= 0) {
1705 if (nfnd < 0) {
1706 perror("abort");
1707 }
1708 if (ptabflg)
1709 code = -1;
1710 lostpeer();
1711 }
1712 (void) getreply(0);
1713 (void) getreply(0);
1714 }
1715 if (proxy)
1716 pswitch(0);
1717 switch (oldtype) {
1718 case 0:
1719 break;
1720 case TYPE_A:
1721 setascii();
1722 break;
1723 case TYPE_I:
1724 setbinary();
1725 break;
1726 case TYPE_E:
1727 setebcdic();
1728 break;
1729 case TYPE_L:
1730 settenex();
1731 break;
1732 }
1733 pswitch(1);
1734 if (ptabflg)
1735 code = -1;
1736 null();// (void) signal(SIGINT, oldintr);
1737 }
1738
1739 void reset()
1740 {
1741 // struct
1742 fd_set mask;
1743 int nfnd = 1;
1744
1745 FD_ZERO(&mask);
1746 while (nfnd > 0) {
1747 // FD_SET(fileno(cin), &mask); // Chris
1748 if ((nfnd = empty(&mask,0)) < 0) {
1749 perror("reset");
1750 code = -1;
1751 lostpeer();
1752 }
1753 else if (nfnd) {
1754 (void) getreply(0);
1755 }
1756 }
1757 }
1758
1759 char *
1760 gunique(local)
1761 char *local;
1762 {
1763 static char new[MAXPATHLEN];
1764 char *cp = rindex(local, '/');
1765 int d, count=0;
1766 char ext = '1';
1767
1768 if (cp)
1769 *cp = '\0';
1770 d = access(cp ? local : ".", 2);
1771 if (cp)
1772 *cp = '/';
1773 if (d < 0) {
1774 perror(local);
1775 return((char *) 0);
1776 }
1777 (void) strcpy(new, local);
1778 cp = new + strlen(new);
1779 *cp++ = '.';
1780 while (!d) {
1781 if (++count == 100) {
1782 printf("runique: can't find unique file name.\n");
1783 (void) fflush(stdout);
1784 return((char *) 0);
1785 }
1786 *cp++ = ext;
1787 *cp = '\0';
1788 if (ext == '9')
1789 ext = '0';
1790 else
1791 ext++;
1792 if ((d = access(new, 0)) < 0)
1793 break;
1794 if (ext != '0')
1795 cp--;
1796 else if (*(cp - 2) == '.')
1797 *(cp - 1) = '1';
1798 else {
1799 *(cp - 2) = *(cp - 2) + 1;
1800 cp--;
1801 }
1802 }
1803 return(new);
1804 }
1805
1806 int null(void)
1807 {
1808 return 0;
1809 }