/[inetutils]/inetutils/ftp/ftp.c
ViewVC logotype

Contents of /inetutils/ftp/ftp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.22 - (show annotations) (download)
Tue Feb 27 17:07:12 2001 UTC (23 years, 1 month ago) by alainm
Branch: MAIN
Changes since 1.21: +7 -0 lines
File MIME type: text/plain
Correct a bug when exploging macros.

1 /*
2 * Copyright (c) 1985, 1989, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #ifndef lint
31 static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
32 #endif /* not lint */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include <sys/param.h>
39 #include <sys/stat.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
42 #ifdef TIME_WITH_SYS_TIME
43 # include <sys/time.h>
44 # include <time.h>
45 #else
46 # ifdef HAVE_SYS_TIME_H
47 # include <sys/time.h>
48 # else
49 # include <time.h>
50 # endif
51 #endif
52 #include <sys/file.h>
53
54 #include <netinet/in.h>
55 #ifdef HAVE_NETINET_IN_SYSTM_H
56 #include <netinet/in_systm.h>
57 #endif
58 #ifdef HAVE_NETINET_IP_H
59 #include <netinet/ip.h>
60 #endif
61 #include <arpa/inet.h>
62 #include <arpa/ftp.h>
63 #include <arpa/telnet.h>
64
65 #include <ctype.h>
66 #include <err.h>
67 #include <errno.h>
68 #include <fcntl.h>
69 #include <netdb.h>
70 #include <pwd.h>
71 #include <signal.h>
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <string.h>
75 #include <unistd.h>
76 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
77 #include <stdarg.h>
78 #else
79 #include <varargs.h>
80 #endif
81 #ifdef HAVE_SYS_SELECT_H
82 #include <sys/select.h>
83 #endif
84
85 #include "ftp_var.h"
86
87 #ifndef HAVE_FCLOSE_DECL
88 /* Some systems don't declare fclose in <stdio.h>, so do it ourselves. */
89 extern int fclose __P ((FILE *));
90 #endif
91
92 #ifndef HAVE_PCLOSE_DECL
93 /* Some systems don't declare pclose in <stdio.h>, so do it ourselves. */
94 extern int pclose __P ((FILE *));
95 #endif
96
97 extern int h_errno;
98
99 struct sockaddr_in hisctladdr;
100 struct sockaddr_in data_addr;
101 int data = -1;
102 int abrtflag = 0;
103 jmp_buf ptabort;
104 int ptabflg;
105 int ptflag = 0;
106 struct sockaddr_in myctladdr;
107 off_t restart_point = 0;
108
109
110 FILE *cin, *cout;
111
112 char *
113 hookup(host, port)
114 char *host;
115 int port;
116 {
117 struct hostent *hp = 0;
118 int s, len, tos;
119 static char hostnamebuf[80];
120
121 memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
122 hisctladdr.sin_addr.s_addr = inet_addr(host);
123 if (hisctladdr.sin_addr.s_addr != -1) {
124 hisctladdr.sin_family = AF_INET;
125 (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));
126 } else {
127 hp = gethostbyname(host);
128 if (hp == NULL) {
129 #ifdef HAVE_HSTRERROR
130 warnx("%s: %s", host, hstrerror(h_errno));
131 #else
132 extern char *__progname;
133 char *pfx =
134 malloc (strlen (__progname) + 2 + strlen (host) + 1);
135 sprintf (pfx, "%s: %s", __progname, host);
136 herror (pfx);
137 #endif
138 code = -1;
139 return ((char *) 0);
140 }
141 hisctladdr.sin_family = hp->h_addrtype;
142 memmove((caddr_t)&hisctladdr.sin_addr,
143 #ifdef HAVE_HOSTENT_H_ADDR_LIST
144 hp->h_addr_list[0],
145 #else
146 hp->h_addr,
147 #endif
148 hp->h_length);
149 (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
150 }
151 hostname = hostnamebuf;
152 s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
153 if (s < 0) {
154 warn("socket");
155 code = -1;
156 return (0);
157 }
158 hisctladdr.sin_port = port;
159 while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
160 #ifdef HAVE_HOSTENT_H_ADDR_LIST
161 if (hp && hp->h_addr_list[1]) {
162 int oerrno = errno;
163 char *ia;
164
165 ia = inet_ntoa(hisctladdr.sin_addr);
166 errno = oerrno;
167 warn("connect to address %s", ia);
168 hp->h_addr_list++;
169 memmove((caddr_t)&hisctladdr.sin_addr,
170 hp->h_addr_list[0], hp->h_length);
171 fprintf(stdout, "Trying %s...\n",
172 inet_ntoa(hisctladdr.sin_addr));
173 (void) close(s);
174 s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
175 if (s < 0) {
176 warn("socket");
177 code = -1;
178 return (0);
179 }
180 continue;
181 }
182 #endif
183 warn("connect");
184 code = -1;
185 goto bad;
186 }
187 len = sizeof (myctladdr);
188 if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
189 warn("getsockname");
190 code = -1;
191 goto bad;
192 }
193 #if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_LOWDELAY)
194 tos = IPTOS_LOWDELAY;
195 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
196 warn("setsockopt TOS (ignored)");
197 #endif
198 cin = fdopen(s, "r");
199 /* dup(s) is for sake of stdio implementations who do not
200 allow two fdopen's on the same file-descriptor */
201 cout = fdopen(dup(s), "w");
202 if (cin == NULL || cout == NULL) {
203 warnx("fdopen failed.");
204 if (cin)
205 (void) fclose(cin);
206 if (cout)
207 (void) fclose(cout);
208 code = -1;
209 goto bad;
210 }
211 if (verbose)
212 printf("Connected to %s.\n", hostname);
213 if (getreply(0) > 2) { /* read startup message from server */
214 if (cin)
215 (void) fclose(cin);
216 if (cout)
217 (void) fclose(cout);
218 code = -1;
219 goto bad;
220 }
221 #ifdef SO_OOBINLINE
222 {
223 int on = 1;
224
225 if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on))
226 < 0 && debug) {
227 warn("setsockopt");
228 }
229 }
230 #endif /* SO_OOBINLINE */
231
232 return (hostname);
233 bad:
234 (void) close(s);
235 return ((char *)0);
236 }
237
238 int
239 login(host)
240 char *host;
241 {
242 char tmp[80];
243 char *user, *pass, *acct;
244 int n, aflag = 0;
245
246 user = pass = acct = 0;
247 if (ruserpass(host, &user, &pass, &acct) < 0) {
248 code = -1;
249 return (0);
250 }
251 while (user == NULL) {
252 char *myname = getlogin();
253
254 if (myname == NULL) {
255 struct passwd *pp = getpwuid(getuid());
256
257 if (pp != NULL)
258 myname = pp->pw_name;
259 }
260 if (myname)
261 printf("Name (%s:%s): ", host, myname);
262 else
263 printf("Name (%s): ", host);
264 if (fgets(tmp, sizeof(tmp) - 1, stdin)) {
265 /* If they press Ctrl-d immediately, it's empty. */
266 tmp[strlen(tmp) - 1] = '\0';
267 } else
268 *tmp = '\0';
269 if (*tmp == '\0')
270 user = myname;
271 else
272 user = tmp;
273 }
274 n = command("USER %s", user);
275 if (n == CONTINUE) {
276 if (pass == NULL)
277 pass = getpass("Password:");
278 n = command("PASS %s", pass);
279 }
280 if (n == CONTINUE) {
281 aflag++;
282 acct = getpass("Account:");
283 n = command("ACCT %s", acct);
284 }
285 if (n != COMPLETE) {
286 warnx("Login failed.");
287 return (0);
288 }
289 if (!aflag && acct != NULL)
290 (void) command("ACCT %s", acct);
291 if (proxy)
292 return (1);
293 for (n = 0; n < macnum; ++n) {
294 if (!strcmp("init", macros[n].mac_name)) {
295 #if HAVE_LIBREADLINE
296 if (line)
297 free (line);
298 line = calloc (200, sizeof (*line));
299 if (!line)
300 quit (0, 0);
301 #endif
302 (void) strcpy(line, "$init");
303 makeargv();
304 domacro(margc, margv);
305 break;
306 }
307 }
308 return (1);
309 }
310
311 void
312 cmdabort(sig)
313 int sig;
314 {
315
316 printf("\n");
317 (void) fflush(stdout);
318 abrtflag++;
319 if (ptflag)
320 longjmp(ptabort,1);
321 }
322
323 /*VARARGS*/
324 int
325 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
326 command (const char *fmt, ...)
327 #else
328 command(va_alist)
329 va_dcl
330 #endif
331 {
332 va_list ap;
333 #if !(defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__)
334 const char *fmt;
335 #endif
336 int r;
337 sig_t oldintr;
338
339 abrtflag = 0;
340 if (debug) {
341 printf("---> ");
342 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
343 va_start (ap, fmt);
344 #else
345 va_start(ap);
346 fmt = va_arg(ap, char *);
347 #endif
348 if (strncmp("PASS ", fmt, 5) == 0)
349 printf("PASS XXXX");
350 else
351 vfprintf(stdout, fmt, ap);
352 va_end(ap);
353 printf("\n");
354 (void) fflush(stdout);
355 }
356 if (cout == NULL) {
357 warn("No control connection for command");
358 code = -1;
359 return (0);
360 }
361 oldintr = signal(SIGINT, cmdabort);
362 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
363 va_start (ap, fmt);
364 #else
365 va_start(ap);
366 fmt = va_arg(ap, char *);
367 #endif
368 vfprintf(cout, fmt, ap);
369 va_end(ap);
370 fprintf(cout, "\r\n");
371 (void) fflush(cout);
372 cpend = 1;
373 r = getreply(!strcmp(fmt, "QUIT"));
374 if (abrtflag && oldintr != SIG_IGN)
375 (*oldintr)(SIGINT);
376 (void) signal(SIGINT, oldintr);
377 return (r);
378 }
379
380 char reply_string[BUFSIZ]; /* last line of previous reply */
381
382 int
383 getreply(expecteof)
384 int expecteof;
385 {
386 int c, n;
387 int dig;
388 int originalcode = 0, continuation = 0;
389 sig_t oldintr;
390 int pflag = 0;
391 char *cp, *pt = pasv;
392
393 oldintr = signal(SIGINT, cmdabort);
394 for (;;) {
395 dig = n = code = 0;
396 cp = reply_string;
397 while ((c = getc(cin)) != '\n') {
398 if (c == IAC) { /* handle telnet commands */
399 switch (c = getc(cin)) {
400 case WILL:
401 case WONT:
402 c = getc(cin);
403 fprintf(cout, "%c%c%c", IAC, DONT, c);
404 (void) fflush(cout);
405 break;
406 case DO:
407 case DONT:
408 c = getc(cin);
409 fprintf(cout, "%c%c%c", IAC, WONT, c);
410 (void) fflush(cout);
411 break;
412 default:
413 break;
414 }
415 continue;
416 }
417 dig++;
418 if (c == EOF) {
419 if (expecteof) {
420 (void) signal(SIGINT,oldintr);
421 code = 221;
422 return (0);
423 }
424 lostpeer();
425 if (verbose) {
426 printf("421 Service not available, remote server has closed connection\n");
427 (void) fflush(stdout);
428 }
429 code = 421;
430 return (4);
431 }
432 if (c != '\r' && (verbose > 0 ||
433 (verbose > -1 && n == '5' && dig > 4))) {
434 if (proxflag &&
435 (dig == 1 || dig == 5 && verbose == 0))
436 printf("%s:",hostname);
437 (void) putchar(c);
438 }
439 if (dig < 4 && isdigit(c))
440 code = code * 10 + (c - '0');
441 if (!pflag && code == 227)
442 pflag = 1;
443 if (dig > 4 && pflag == 1 && isdigit(c))
444 pflag = 2;
445 if (pflag == 2) {
446 if (c != '\r' && c != ')')
447 *pt++ = c;
448 else {
449 *pt = '\0';
450 pflag = 3;
451 }
452 }
453 if (dig == 4 && c == '-') {
454 if (continuation)
455 code = 0;
456 continuation++;
457 }
458 if (n == 0)
459 n = c;
460 if (cp < &reply_string[sizeof(reply_string) - 1])
461 *cp++ = c;
462 }
463 if (verbose > 0 || verbose > -1 && n == '5') {
464 (void) putchar(c);
465 (void) fflush (stdout);
466 }
467 if (continuation && code != originalcode) {
468 if (originalcode == 0)
469 originalcode = code;
470 continue;
471 }
472 *cp = '\0';
473 if (n != '1')
474 cpend = 0;
475 (void) signal(SIGINT,oldintr);
476 if (code == 421 || originalcode == 421)
477 lostpeer();
478 if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
479 (*oldintr)(SIGINT);
480 return (n - '0');
481 }
482 }
483
484 int
485 empty(mask, sec)
486 fd_set *mask;
487 int sec;
488 {
489 struct timeval t;
490
491 t.tv_sec = (long) sec;
492 t.tv_usec = 0;
493 return (select(32, mask, (fd_set *) 0, (fd_set *) 0, &t));
494 }
495
496 jmp_buf sendabort;
497
498 void
499 abortsend(sig)
500 int sig;
501 {
502
503 mflag = 0;
504 abrtflag = 0;
505 printf("\nsend aborted\nwaiting for remote to finish abort\n");
506 (void) fflush(stdout);
507 longjmp(sendabort, 1);
508 }
509
510 void
511 sendrequest(cmd, local, remote, printnames)
512 char *cmd, *local, *remote;
513 int printnames;
514 {
515 struct stat st;
516 struct timeval start, stop;
517 int c, d;
518 FILE *fin, *dout = 0, *popen();
519 int (*closefunc) __P((FILE *));
520 sig_t oldintr, oldintp;
521 long bytes = 0, local_hashbytes=hashbytes;
522 char *lmode, buf[BUFSIZ], *bufp;
523
524 if (verbose && printnames) {
525 if (local && *local != '-')
526 printf("local: %s ", local);
527 if (remote)
528 printf("remote: %s\n", remote);
529 }
530 if (proxy) {
531 proxtrans(cmd, local, remote);
532 return;
533 }
534 if (curtype != type)
535 changetype(type, 0);
536 closefunc = NULL;
537 oldintr = NULL;
538 oldintp = NULL;
539 lmode = "w";
540 if (setjmp(sendabort)) {
541 while (cpend) {
542 (void) getreply(0);
543 }
544 if (data >= 0) {
545 (void) close(data);
546 data = -1;
547 }
548 if (oldintr)
549 (void) signal(SIGINT,oldintr);
550 if (oldintp)
551 (void) signal(SIGPIPE,oldintp);
552 code = -1;
553 return;
554 }
555 oldintr = signal(SIGINT, abortsend);
556 if (strcmp(local, "-") == 0)
557 fin = stdin;
558 else if (*local == '|') {
559 oldintp = signal(SIGPIPE,SIG_IGN);
560 fin = popen(local + 1, "r");
561 if (fin == NULL) {
562 warn("%s", local + 1);
563 (void) signal(SIGINT, oldintr);
564 (void) signal(SIGPIPE, oldintp);
565 code = -1;
566 return;
567 }
568 closefunc = pclose;
569 } else {
570 fin = fopen(local, "r");
571 if (fin == NULL) {
572 warn("local: %s", local);
573 (void) signal(SIGINT, oldintr);
574 code = -1;
575 return;
576 }
577 closefunc = fclose;
578 if (fstat(fileno(fin), &st) < 0 ||
579 (st.st_mode&S_IFMT) != S_IFREG) {
580 fprintf(stdout, "%s: not a plain file.\n", local);
581 (void) signal(SIGINT, oldintr);
582 fclose(fin);
583 code = -1;
584 return;
585 }
586 }
587 if (initconn()) {
588 (void) signal(SIGINT, oldintr);
589 if (oldintp)
590 (void) signal(SIGPIPE, oldintp);
591 code = -1;
592 if (closefunc != NULL)
593 (*closefunc)(fin);
594 return;
595 }
596 if (setjmp(sendabort))
597 goto abort;
598
599 if (restart_point &&
600 (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
601 int rc;
602
603 switch (curtype) {
604 case TYPE_A:
605 rc = fseek(fin, (long) restart_point, SEEK_SET);
606 break;
607 case TYPE_I:
608 case TYPE_L:
609 rc = lseek(fileno(fin), restart_point, SEEK_SET);
610 break;
611 }
612 if (rc < 0) {
613 warn("local: %s", local);
614 restart_point = 0;
615 if (closefunc != NULL)
616 (*closefunc)(fin);
617 return;
618 }
619 if (command("REST %ld", (long) restart_point)
620 != CONTINUE) {
621 restart_point = 0;
622 if (closefunc != NULL)
623 (*closefunc)(fin);
624 return;
625 }
626 restart_point = 0;
627 lmode = "r+w";
628 }
629 if (remote) {
630 if (command("%s %s", cmd, remote) != PRELIM) {
631 (void) signal(SIGINT, oldintr);
632 if (oldintp)
633 (void) signal(SIGPIPE, oldintp);
634 if (closefunc != NULL)
635 (*closefunc)(fin);
636 return;
637 }
638 } else
639 if (command("%s", cmd) != PRELIM) {
640 (void) signal(SIGINT, oldintr);
641 if (oldintp)
642 (void) signal(SIGPIPE, oldintp);
643 if (closefunc != NULL)
644 (*closefunc)(fin);
645 return;
646 }
647 dout = dataconn(lmode);
648 if (dout == NULL)
649 goto abort;
650 (void) gettimeofday(&start, (struct timezone *)0);
651 oldintp = signal(SIGPIPE, SIG_IGN);
652 switch (curtype) {
653
654 case TYPE_I:
655 case TYPE_L:
656 errno = d = 0;
657 while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
658 bytes += c;
659 for (bufp = buf; c > 0; c -= d, bufp += d)
660 if ((d = write(fileno(dout), bufp, c)) <= 0)
661 break;
662 if (hash) {
663 while (bytes >= local_hashbytes) {
664 (void) putchar('#');
665 local_hashbytes += hashbytes;
666 }
667 (void) fflush(stdout);
668 }
669 }
670 if (hash && bytes > 0) {
671 if (bytes < local_hashbytes)
672 (void) putchar('#');
673 (void) putchar('\n');
674 (void) fflush(stdout);
675 }
676 if (c < 0)
677 warn("local: %s", local);
678 if (d < 0) {
679 if (errno != EPIPE)
680 warn("netout");
681 bytes = -1;
682 }
683 break;
684
685 case TYPE_A:
686 while ((c = getc(fin)) != EOF) {
687 if (c == '\n') {
688 while (hash && (bytes >= local_hashbytes)) {
689 (void) putchar('#');
690 (void) fflush(stdout);
691 local_hashbytes += hashbytes;
692 }
693 if (ferror(dout))
694 break;
695 (void) putc('\r', dout);
696 bytes++;
697 }
698 (void) putc(c, dout);
699 bytes++;
700 /* if (c == '\r') { */
701 /* (void) putc('\0', dout); // this violates rfc */
702 /* bytes++; */
703 /* } */
704 }
705 if (hash) {
706 if (bytes < local_hashbytes)
707 (void) putchar('#');
708 (void) putchar('\n');
709 (void) fflush(stdout);
710 }
711 if (ferror(fin))
712 warn("local: %s", local);
713 if (ferror(dout)) {
714 if (errno != EPIPE)
715 warn("netout");
716 bytes = -1;
717 }
718 break;
719 }
720 if (closefunc != NULL)
721 (*closefunc)(fin);
722 (void) fclose(dout);
723 (void) gettimeofday(&stop, (struct timezone *)0);
724 (void) getreply(0);
725 (void) signal(SIGINT, oldintr);
726 if (oldintp)
727 (void) signal(SIGPIPE, oldintp);
728 if (bytes > 0)
729 ptransfer("sent", bytes, &start, &stop);
730 return;
731 abort:
732 (void) signal(SIGINT, oldintr);
733 if (oldintp)
734 (void) signal(SIGPIPE, oldintp);
735 if (!cpend) {
736 code = -1;
737 return;
738 }
739 if (data >= 0) {
740 (void) close(data);
741 data = -1;
742 }
743 if (dout)
744 (void) fclose(dout);
745 (void) getreply(0);
746 code = -1;
747 if (closefunc != NULL && fin != NULL)
748 (*closefunc)(fin);
749 (void) gettimeofday(&stop, (struct timezone *)0);
750 if (bytes > 0)
751 ptransfer("sent", bytes, &start, &stop);
752 }
753
754 jmp_buf recvabort;
755
756 void
757 abortrecv(sig)
758 int sig;
759 {
760
761 mflag = 0;
762 abrtflag = 0;
763 printf("\nreceive aborted\nwaiting for remote to finish abort\n");
764 (void) fflush(stdout);
765 longjmp(recvabort, 1);
766 }
767
768 void
769 recvrequest(cmd, local, remote, lmode, printnames)
770 char *cmd, *local, *remote, *lmode;
771 int printnames;
772 {
773 FILE *fout, *din = 0;
774 int (*closefunc) __P((FILE *));
775 sig_t oldintr, oldintp;
776 int c, d, is_retr, tcrflag, bare_lfs = 0, blksize;
777 static int bufsize=0;
778 static char *buf;
779 long bytes = 0, local_hashbytes = hashbytes;
780 struct timeval start, stop;
781 struct stat st;
782
783 is_retr = strcmp(cmd, "RETR") == 0;
784 if (is_retr && verbose && printnames) {
785 if (local && *local != '-')
786 printf("local: %s ", local);
787 if (remote)
788 printf("remote: %s\n", remote);
789 }
790 if (proxy && is_retr) {
791 proxtrans(cmd, local, remote);
792 return;
793 }
794 closefunc = NULL;
795 oldintr = NULL;
796 oldintp = NULL;
797 tcrflag = !crflag && is_retr;
798 if (setjmp(recvabort)) {
799 while (cpend) {
800 (void) getreply(0);
801 }
802 if (data >= 0) {
803 (void) close(data);
804 data = -1;
805 }
806 if (oldintr)
807 (void) signal(SIGINT, oldintr);
808 code = -1;
809 return;
810 }
811 oldintr = signal(SIGINT, abortrecv);
812 if (strcmp(local, "-") && *local != '|') {
813 if (runique && (local = gunique(local)) == NULL) {
814 (void) signal(SIGINT, oldintr);
815 code = -1;
816 return;
817 }
818 }
819 if (!is_retr) {
820 if (curtype != TYPE_A)
821 changetype(TYPE_A, 0);
822 } else if (curtype != type)
823 changetype(type, 0);
824 if (initconn()) {
825 (void) signal(SIGINT, oldintr);
826 code = -1;
827 return;
828 }
829 if (setjmp(recvabort))
830 goto abort;
831 if (is_retr && restart_point &&
832 command("REST %ld", (long) restart_point) != CONTINUE)
833 return;
834 if (remote) {
835 if (command("%s %s", cmd, remote) != PRELIM) {
836 (void) signal(SIGINT, oldintr);
837 return;
838 }
839 } else {
840 if (command("%s", cmd) != PRELIM) {
841 (void) signal(SIGINT, oldintr);
842 return;
843 }
844 }
845 din = dataconn("r");
846 if (din == NULL)
847 goto abort;
848 if (strcmp(local, "-") == 0)
849 fout = stdout;
850 else if (*local == '|') {
851 oldintp = signal(SIGPIPE, SIG_IGN);
852 fout = popen(local + 1, "w");
853 if (fout == NULL) {
854 warn("%s", local+1);
855 goto abort;
856 }
857 closefunc = pclose;
858 } else {
859 fout = fopen(local, lmode);
860 if (fout == NULL) {
861 warn("local: %s", local);
862 goto abort;
863 }
864 closefunc = fclose;
865 }
866 if (fstat(fileno(fout), &st) < 0 || ST_BLKSIZE(st) == 0)
867 blksize = BUFSIZ;
868 else
869 blksize = ST_BLKSIZE(st);
870 if (blksize > bufsize) {
871 if (buf)
872 (void) free(buf);
873 buf = malloc((unsigned)blksize);
874 if (buf == NULL) {
875 warn("malloc");
876 bufsize = 0;
877 goto abort;
878 }
879 bufsize = blksize;
880 }
881 (void) gettimeofday(&start, (struct timezone *)0);
882 switch (curtype) {
883
884 case TYPE_I:
885 case TYPE_L:
886 if (restart_point &&
887 lseek(fileno(fout), restart_point, SEEK_SET) < 0) {
888 warn("local: %s", local);
889 if (closefunc != NULL)
890 (*closefunc)(fout);
891 return;
892 }
893 errno = d = 0;
894 while ((c = read(fileno(din), buf, bufsize)) > 0) {
895 if ((d = write(fileno(fout), buf, c)) != c)
896 break;
897 bytes += c;
898 if (hash) {
899 while (bytes >= local_hashbytes) {
900 (void) putchar('#');
901 local_hashbytes += hashbytes;
902 }
903 (void) fflush(stdout);
904 }
905 }
906 if (hash && bytes > 0) {
907 if (bytes < local_hashbytes)
908 (void) putchar('#');
909 (void) putchar('\n');
910 (void) fflush(stdout);
911 }
912 if (c < 0) {
913 if (errno != EPIPE)
914 warn("netin");
915 bytes = -1;
916 }
917 if (d < c) {
918 if (d < 0)
919 warn("local: %s", local);
920 else
921 warnx("%s: short write", local);
922 }
923 break;
924
925 case TYPE_A:
926 if (restart_point) {
927 int i, n, ch;
928
929 if (fseek(fout, 0L, SEEK_SET) < 0)
930 goto done;
931 n = restart_point;
932 for (i = 0; i++ < n;) {
933 if ((ch = getc(fout)) == EOF)
934 goto done;
935 if (ch == '\n')
936 i++;
937 }
938 if (fseek(fout, 0L, SEEK_CUR) < 0) {
939 done:
940 warn("local: %s", local);
941 if (closefunc != NULL)
942 (*closefunc)(fout);
943 return;
944 }
945 }
946 while ((c = getc(din)) != EOF) {
947 if (c == '\n')
948 bare_lfs++;
949 while (c == '\r') {
950 while (hash && (bytes >= local_hashbytes)) {
951 (void) putchar('#');
952 (void) fflush(stdout);
953 local_hashbytes += hashbytes;
954 }
955 bytes++;
956 if ((c = getc(din)) != '\n' || tcrflag) {
957 if (ferror(fout))
958 goto break2;
959 (void) putc('\r', fout);
960 if (c == '\0') {
961 bytes++;
962 goto contin2;
963 }
964 if (c == EOF)
965 goto contin2;
966 }
967 }
968 (void) putc(c, fout);
969 bytes++;
970 contin2: ;
971 }
972 break2:
973 if (bare_lfs) {
974 printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
975 printf("File may not have transferred correctly.\n");
976 }
977 if (hash) {
978 if (bytes < local_hashbytes)
979 (void) putchar('#');
980 (void) putchar('\n');
981 (void) fflush(stdout);
982 }
983 if (ferror(din)) {
984 if (errno != EPIPE)
985 warn("netin");
986 bytes = -1;
987 }
988 if (ferror(fout))
989 warn("local: %s", local);
990 break;
991 }
992 if (closefunc != NULL)
993 (*closefunc)(fout);
994 (void) signal(SIGINT, oldintr);
995 if (oldintp)
996 (void) signal(SIGPIPE, oldintp);
997 (void) fclose(din);
998 (void) gettimeofday(&stop, (struct timezone *)0);
999 (void) getreply(0);
1000 if (bytes > 0 && is_retr)
1001 ptransfer("received", bytes, &start, &stop);
1002 return;
1003 abort:
1004
1005 /* abort using RFC959 recommended IP,SYNC sequence */
1006
1007 if (oldintp)
1008 (void) signal(SIGPIPE, oldintr);
1009 (void) signal(SIGINT, SIG_IGN);
1010 if (!cpend) {
1011 code = -1;
1012 (void) signal(SIGINT, oldintr);
1013 return;
1014 }
1015
1016 abort_remote(din);
1017 code = -1;
1018 if (data >= 0) {
1019 (void) close(data);
1020 data = -1;
1021 }
1022 if (closefunc != NULL && fout != NULL)
1023 (*closefunc)(fout);
1024 if (din)
1025 (void) fclose(din);
1026 (void) gettimeofday(&stop, (struct timezone *)0);
1027 if (bytes > 0)
1028 ptransfer("received", bytes, &start, &stop);
1029 (void) signal(SIGINT, oldintr);
1030 }
1031
1032 /*
1033 * Need to start a listen on the data channel before we send the command,
1034 * otherwise the server's connect may fail.
1035 */
1036 int
1037 initconn()
1038 {
1039 char *p, *a;
1040 int result, len, tmpno = 0;
1041 int on = 1;
1042 int a0, a1, a2, a3, p0, p1;
1043
1044 if (passivemode) {
1045 data = socket(AF_INET, SOCK_STREAM, 0);
1046 if (data < 0) {
1047 perror("ftp: socket");
1048 return(1);
1049 }
1050 if ((options & SO_DEBUG) &&
1051 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
1052 sizeof (on)) < 0)
1053 perror("ftp: setsockopt (ignored)");
1054 if (command("PASV") != COMPLETE) {
1055 printf("Passive mode refused.\n");
1056 goto bad;
1057 }
1058
1059 /*
1060 * What we've got at this point is a string of comma
1061 * separated one-byte unsigned integer values.
1062 * The first four are the an IP address. The fifth is
1063 * the MSB of the port number, the sixth is the LSB.
1064 * From that we'll prepare a sockaddr_in.
1065 */
1066
1067 if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",
1068 &a0, &a1, &a2, &a3, &p0, &p1) != 6) {
1069 printf("Passive mode address scan failure. Shouldn't happen!\n");
1070 goto bad;
1071 }
1072
1073 bzero(&data_addr, sizeof(data_addr));
1074 data_addr.sin_family = AF_INET;
1075 a = (char *)&data_addr.sin_addr.s_addr;
1076 a[0] = a0 & 0xff;
1077 a[1] = a1 & 0xff;
1078 a[2] = a2 & 0xff;
1079 a[3] = a3 & 0xff;
1080 p = (char *)&data_addr.sin_port;
1081 p[0] = p0 & 0xff;
1082 p[1] = p1 & 0xff;
1083
1084 if (connect(data, (struct sockaddr *)&data_addr,
1085 sizeof(data_addr)) < 0) {
1086 perror("ftp: connect");
1087 goto bad;
1088 }
1089 #if defined(IP_TOS) && defined(IPTOS_THROUGPUT)
1090 on = IPTOS_THROUGHPUT;
1091 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on,
1092 sizeof(int)) < 0)
1093 perror("ftp: setsockopt TOS (ignored)");
1094 #endif
1095 return(0);
1096 }
1097
1098 noport:
1099 data_addr = myctladdr;
1100 if (sendport)
1101 data_addr.sin_port = 0; /* let system pick one */
1102 if (data != -1)
1103 (void) close(data);
1104 data = socket(AF_INET, SOCK_STREAM, 0);
1105 if (data < 0) {
1106 warn("socket");
1107 if (tmpno)
1108 sendport = 1;
1109 return (1);
1110 }
1111 if (!sendport)
1112 if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
1113 warn("setsockopt (reuse address)");
1114 goto bad;
1115 }
1116 if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
1117 warn("bind");
1118 goto bad;
1119 }
1120 if (options & SO_DEBUG &&
1121 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
1122 warn("setsockopt (ignored)");
1123 len = sizeof (data_addr);
1124 if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
1125 warn("getsockname");
1126 goto bad;
1127 }
1128 if (listen(data, 1) < 0)
1129 warn("listen");
1130 if (sendport) {
1131 a = (char *)&data_addr.sin_addr;
1132 p = (char *)&data_addr.sin_port;
1133 #define UC(b) (((int)b)&0xff)
1134 result =
1135 command("PORT %d,%d,%d,%d,%d,%d",
1136 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
1137 UC(p[0]), UC(p[1]));
1138 if (result == ERROR && sendport == -1) {
1139 sendport = 0;
1140 tmpno = 1;
1141 goto noport;
1142 }
1143 return (result != COMPLETE);
1144 }
1145 if (tmpno)
1146 sendport = 1;
1147 #if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_THROUGHPUT)
1148 on = IPTOS_THROUGHPUT;
1149 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
1150 warn("setsockopt TOS (ignored)");
1151 #endif
1152 return (0);
1153 bad:
1154 (void) close(data), data = -1;
1155 if (tmpno)
1156 sendport = 1;
1157 return (1);
1158 }
1159
1160 FILE *
1161 dataconn(lmode)
1162 char *lmode;
1163 {
1164 struct sockaddr_in from;
1165 int s, fromlen = sizeof (from), tos;
1166
1167 if (passivemode)
1168 return (fdopen(data, lmode));
1169
1170 s = accept(data, (struct sockaddr *) &from, &fromlen);
1171 if (s < 0) {
1172 warn("accept");
1173 (void) close(data), data = -1;
1174 return (NULL);
1175 }
1176 (void) close(data);
1177 data = s;
1178 #if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_THROUGHPUT)
1179 tos = IPTOS_THROUGHPUT;
1180 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
1181 warn("setsockopt TOS (ignored)");
1182 #endif
1183 return (fdopen(data, lmode));
1184 }
1185
1186 void
1187 ptransfer(direction, bytes, t0, t1)
1188 char *direction;
1189 long bytes;
1190 struct timeval *t0, *t1;
1191 {
1192 struct timeval td;
1193 float s;
1194 long bs;
1195
1196 if (verbose) {
1197 tvsub(&td, t1, t0);
1198 s = td.tv_sec + (td.tv_usec / 1000000.);
1199 #define nz(x) ((x) == 0 ? 1 : (x))
1200 bs = bytes / nz(s);
1201 printf("%ld bytes %s in %.3g seconds (%ld bytes/s)\n",
1202 bytes, direction, s, bs);
1203 }
1204 }
1205
1206 /*
1207 void
1208 tvadd(tsum, t0)
1209 struct timeval *tsum, *t0;
1210 {
1211
1212 tsum->tv_sec += t0->tv_sec;
1213 tsum->tv_usec += t0->tv_usec;
1214 if (tsum->tv_usec > 1000000)
1215 tsum->tv_sec++, tsum->tv_usec -= 1000000;
1216 }
1217 */
1218
1219 void
1220 tvsub(tdiff, t1, t0)
1221 struct timeval *tdiff, *t1, *t0;
1222 {
1223
1224 tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
1225 tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
1226 if (tdiff->tv_usec < 0)
1227 tdiff->tv_sec--, tdiff->tv_usec += 1000000;
1228 }
1229
1230 void
1231 psabort(sig)
1232 int sig;
1233 {
1234
1235 abrtflag++;
1236 }
1237
1238 void
1239 pswitch(flag)
1240 int flag;
1241 {
1242 sig_t oldintr;
1243 static struct comvars {
1244 int connect;
1245 char *name;
1246 struct sockaddr_in mctl;
1247 struct sockaddr_in hctl;
1248 FILE *in;
1249 FILE *out;
1250 int tpe;
1251 int curtpe;
1252 int cpnd;
1253 int sunqe;
1254 int runqe;
1255 int mcse;
1256 int ntflg;
1257 char nti[17];
1258 char nto[17];
1259 int mapflg;
1260 char *mi;
1261 char *mo;
1262 } proxstruct = {0}, tmpstruct = {0};
1263 struct comvars *ip, *op;
1264
1265 abrtflag = 0;
1266 oldintr = signal(SIGINT, psabort);
1267 if (flag) {
1268 if (proxy)
1269 return;
1270 ip = &tmpstruct;
1271 op = &proxstruct;
1272 proxy++;
1273 } else {
1274 if (!proxy)
1275 return;
1276 ip = &proxstruct;
1277 op = &tmpstruct;
1278 proxy = 0;
1279 }
1280 ip->connect = connected;
1281 connected = op->connect;
1282
1283 if (ip->name)
1284 free (ip->name);
1285 ip->name = hostname;
1286 hostname = op->name;
1287 op->name = 0;
1288
1289 ip->hctl = hisctladdr;
1290 hisctladdr = op->hctl;
1291 ip->mctl = myctladdr;
1292 myctladdr = op->mctl;
1293 ip->in = cin;
1294 cin = op->in;
1295 ip->out = cout;
1296 cout = op->out;
1297 ip->tpe = type;
1298 type = op->tpe;
1299 ip->curtpe = curtype;
1300 curtype = op->curtpe;
1301 ip->cpnd = cpend;
1302 cpend = op->cpnd;
1303 ip->sunqe = sunique;
1304 sunique = op->sunqe;
1305 ip->runqe = runique;
1306 runique = op->runqe;
1307 ip->mcse = mcase;
1308 mcase = op->mcse;
1309 ip->ntflg = ntflag;
1310 ntflag = op->ntflg;
1311 (void) strncpy(ip->nti, ntin, sizeof(ntin) - 1);
1312 (ip->nti)[strlen(ip->nti)] = '\0';
1313 (void) strcpy(ntin, op->nti);
1314 (void) strncpy(ip->nto, ntout, sizeof(ntout) - 1);
1315 (ip->nto)[strlen(ip->nto)] = '\0';
1316 (void) strcpy(ntout, op->nto);
1317 ip->mapflg = mapflag;
1318 mapflag = op->mapflg;
1319
1320 if (ip->mi)
1321 free (ip->mi);
1322 ip->mi = mapin;
1323 mapin = op->mi;
1324 op->mi = 0;
1325
1326 if (ip->mo)
1327 free (ip->mo);
1328 ip->mo = mapout;
1329 mapout = op->mo;
1330 op->mo = 0;
1331
1332 (void) signal(SIGINT, oldintr);
1333 if (abrtflag) {
1334 abrtflag = 0;
1335 (*oldintr)(SIGINT);
1336 }
1337 }
1338
1339 void
1340 abortpt(sig)
1341 int sig;
1342 {
1343
1344 printf("\n");
1345 (void) fflush(stdout);
1346 ptabflg++;
1347 mflag = 0;
1348 abrtflag = 0;
1349 longjmp(ptabort, 1);
1350 }
1351
1352 void
1353 proxtrans(cmd, local, remote)
1354 char *cmd, *local, *remote;
1355 {
1356 sig_t oldintr;
1357 int secndflag = 0, prox_type, nfnd;
1358 char *cmd2;
1359 fd_set mask;
1360
1361 if (strcmp(cmd, "RETR"))
1362 cmd2 = "RETR";
1363 else
1364 cmd2 = runique ? "STOU" : "STOR";
1365 if ((prox_type = type) == 0) {
1366 if (unix_server && unix_proxy)
1367 prox_type = TYPE_I;
1368 else
1369 prox_type = TYPE_A;
1370 }
1371 if (curtype != prox_type)
1372 changetype(prox_type, 1);
1373 if (command("PASV") != COMPLETE) {
1374 printf("proxy server does not support third party transfers.\n");
1375 return;
1376 }
1377 pswitch(0);
1378 if (!connected) {
1379 printf("No primary connection\n");
1380 pswitch(1);
1381 code = -1;
1382 return;
1383 }
1384 if (curtype != prox_type)
1385 changetype(prox_type, 1);
1386 if (command("PORT %s", pasv) != COMPLETE) {
1387 pswitch(1);
1388 return;
1389 }
1390 if (setjmp(ptabort))
1391 goto abort;
1392 oldintr = signal(SIGINT, abortpt);
1393 if (command("%s %s", cmd, remote) != PRELIM) {
1394 (void) signal(SIGINT, oldintr);
1395 pswitch(1);
1396 return;
1397 }
1398 sleep(2);
1399 pswitch(1);
1400 secndflag++;
1401 if (command("%s %s", cmd2, local) != PRELIM)
1402 goto abort;
1403 ptflag++;
1404 (void) getreply(0);
1405 pswitch(0);
1406 (void) getreply(0);
1407 (void) signal(SIGINT, oldintr);
1408 pswitch(1);
1409 ptflag = 0;
1410 printf("local: %s remote: %s\n", local, remote);
1411 return;
1412 abort:
1413 (void) signal(SIGINT, SIG_IGN);
1414 ptflag = 0;
1415 if (strcmp(cmd, "RETR") && !proxy)
1416 pswitch(1);
1417 else if (!strcmp(cmd, "RETR") && proxy)
1418 pswitch(0);
1419 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
1420 if (command("%s %s", cmd2, local) != PRELIM) {
1421 pswitch(0);
1422 if (cpend)
1423 abort_remote((FILE *) NULL);
1424 }
1425 pswitch(1);
1426 if (ptabflg)
1427 code = -1;
1428 (void) signal(SIGINT, oldintr);
1429 return;
1430 }
1431 if (cpend)
1432 abort_remote((FILE *) NULL);
1433 pswitch(!proxy);
1434 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
1435 if (command("%s %s", cmd2, local) != PRELIM) {
1436 pswitch(0);
1437 if (cpend)
1438 abort_remote((FILE *) NULL);
1439 pswitch(1);
1440 if (ptabflg)
1441 code = -1;
1442 (void) signal(SIGINT, oldintr);
1443 return;
1444 }
1445 }
1446 if (cpend)
1447 abort_remote((FILE *) NULL);
1448 pswitch(!proxy);
1449 if (cpend) {
1450 FD_ZERO(&mask);
1451 FD_SET(fileno(cin), &mask);
1452 if ((nfnd = empty(&mask, 10)) <= 0) {
1453 if (nfnd < 0) {
1454 warn("abort");
1455 }
1456 if (ptabflg)
1457 code = -1;
1458 lostpeer();
1459 }
1460 (void) getreply(0);
1461 (void) getreply(0);
1462 }
1463 if (proxy)
1464 pswitch(0);
1465 pswitch(1);
1466 if (ptabflg)
1467 code = -1;
1468 (void) signal(SIGINT, oldintr);
1469 }
1470
1471 void
1472 reset(argc, argv)
1473 int argc;
1474 char *argv[];
1475 {
1476 fd_set mask;
1477 int nfnd = 1;
1478
1479 FD_ZERO(&mask);
1480 while (nfnd > 0) {
1481 FD_SET(fileno(cin), &mask);
1482 if ((nfnd = empty(&mask,0)) < 0) {
1483 warn("reset");
1484 code = -1;
1485 lostpeer();
1486 }
1487 else if (nfnd) {
1488 (void) getreply(0);
1489 }
1490 }
1491 }
1492
1493 char *
1494 gunique(local)
1495 char *local;
1496 {
1497 static char *new = 0;
1498 char *cp;
1499 int d, count=0;
1500 char ext = '1';
1501
1502 if (new)
1503 free (new);
1504 new = malloc (strlen (local) + 1 + 3 + 1); /* '.' + 100 + '\0' */
1505 if (! new) {
1506 printf ("gunique: malloc failed.\n");
1507 return 0;
1508 }
1509 strcpy (new, local);
1510
1511 cp = new + strlen(new);
1512 *cp++ = '.';
1513 for (;;) {
1514 struct stat st;
1515
1516 if (++count == 100) {
1517 printf("runique: can't find unique file name.\n");
1518 return ((char *) 0);
1519 }
1520 *cp++ = ext;
1521 *cp = '\0';
1522 if (ext == '9')
1523 ext = '0';
1524 else
1525 ext++;
1526
1527 if (stat (new, &st) != 0)
1528 if (errno == ENOENT)
1529 return new;
1530 else
1531 return 0;
1532
1533 if (ext != '0')
1534 cp--;
1535 else if (*(cp - 2) == '.')
1536 *(cp - 1) = '1';
1537 else {
1538 *(cp - 2) = *(cp - 2) + 1;
1539 cp--;
1540 }
1541 }
1542 }
1543
1544 void
1545 abort_remote(din)
1546 FILE *din;
1547 {
1548 char buf[BUFSIZ];
1549 int nfnd;
1550 fd_set mask;
1551
1552 /*
1553 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
1554 * after urgent byte rather than before as is protocol now
1555 */
1556 sprintf(buf, "%c%c%c", IAC, IP, IAC);
1557 if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
1558 warn("abort");
1559 fprintf(cout,"%cABOR\r\n", DM);
1560 (void) fflush(cout);
1561 FD_ZERO(&mask);
1562 FD_SET(fileno(cin), &mask);
1563 if (din) {
1564 FD_SET(fileno(din), &mask);
1565 }
1566 if ((nfnd = empty(&mask, 10)) <= 0) {
1567 if (nfnd < 0) {
1568 warn("abort");
1569 }
1570 if (ptabflg)
1571 code = -1;
1572 lostpeer();
1573 }
1574 if (din && FD_ISSET(fileno(din), &mask)) {
1575 while (read(fileno(din), buf, BUFSIZ) > 0)
1576 /* LOOP */;
1577 }
1578 if (getreply(0) == ERROR && code == 552) {
1579 /* 552 needed for nic style abort */
1580 (void) getreply(0);
1581 }
1582 (void) getreply(0);
1583 }

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26