Line data Source code
1 : /*
2 : Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 : 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014,
4 : 2015 Free Software Foundation, Inc.
5 :
6 : This file is part of GNU Inetutils.
7 :
8 : GNU Inetutils is free software: you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation, either version 3 of the License, or (at
11 : your option) any later version.
12 :
13 : GNU Inetutils is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see `http://www.gnu.org/licenses/'. */
20 :
21 : /*
22 : * Copyright (c) 1985, 1989, 1993, 1994
23 : * The Regents of the University of California. All rights reserved.
24 : *
25 : * Redistribution and use in source and binary forms, with or without
26 : * modification, are permitted provided that the following conditions
27 : * are met:
28 : * 1. Redistributions of source code must retain the above copyright
29 : * notice, this list of conditions and the following disclaimer.
30 : * 2. Redistributions in binary form must reproduce the above copyright
31 : * notice, this list of conditions and the following disclaimer in the
32 : * documentation and/or other materials provided with the distribution.
33 : * 3. Neither the name of the University nor the names of its contributors
34 : * may be used to endorse or promote products derived from this software
35 : * without specific prior written permission.
36 : *
37 : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
38 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
41 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 : * SUCH DAMAGE.
48 : */
49 :
50 : #include <config.h>
51 :
52 : #include <sys/param.h>
53 : #include <sys/stat.h>
54 : #include <sys/ioctl.h>
55 : #include <sys/socket.h>
56 : #include <sys/time.h>
57 : #include <time.h>
58 : #include <sys/file.h>
59 :
60 : #include <netinet/in.h>
61 : #ifdef HAVE_NETINET_IN_SYSTM_H
62 : # include <netinet/in_systm.h>
63 : #endif
64 : #ifdef HAVE_NETINET_IP_H
65 : # include <netinet/ip.h>
66 : #endif
67 : #include <arpa/inet.h>
68 : #include <arpa/ftp.h>
69 : #include <arpa/telnet.h>
70 :
71 : #include <ctype.h>
72 : #include <error.h>
73 : #include <errno.h>
74 : #include <fcntl.h>
75 : #include <netdb.h>
76 : #include <pwd.h>
77 : #include <signal.h>
78 : #include <stdio.h>
79 : #include <stdlib.h>
80 : #include <stdint.h> /* intmax_t */
81 : #include <string.h>
82 : #include <unistd.h>
83 : #include <stdarg.h>
84 : #include <sys/select.h>
85 :
86 : #ifdef HAVE_IDNA_H
87 : # include <idna.h>
88 : #endif
89 :
90 : #include "ftp_var.h"
91 : #include "unused-parameter.h"
92 :
93 : #if !HAVE_DECL_FCLOSE
94 : /* Some systems don't declare fclose in <stdio.h>, so do it ourselves. */
95 : extern int fclose (FILE *);
96 : #endif
97 :
98 : #if !HAVE_DECL_PCLOSE
99 : /* Some systems don't declare pclose in <stdio.h>, so do it ourselves. */
100 : extern int pclose (FILE *);
101 : #endif
102 :
103 : extern int h_errno;
104 :
105 : int data = -1;
106 : int abrtflag = 0;
107 : jmp_buf ptabort;
108 : int ptabflg;
109 : int ptflag = 0;
110 : off_t restart_point = 0;
111 :
112 : struct sockaddr_storage myctladdr;
113 : struct sockaddr_storage hisctladdr;
114 : struct sockaddr_storage data_addr;
115 : socklen_t ctladdrlen; /* Applies to all addresses. */
116 :
117 : /* For temporary resolving: hookup() and initconn()/noport. */
118 : static char ia[INET6_ADDRSTRLEN];
119 : static char portstr[10];
120 :
121 : FILE *cin, *cout;
122 :
123 : #if ! defined FTP_CONNECT_TIMEOUT || FTP_CONNECT_TIMEOUT < 1
124 : # define FTP_CONNECT_TIMEOUT 5
125 : #endif
126 :
127 : char *
128 0 : hookup (char *host, int port)
129 : {
130 0 : struct addrinfo hints, *ai = NULL, *res = NULL;
131 : struct timeval timeout;
132 0 : int status, again = 0;
133 : int s, tos;
134 : socklen_t len;
135 : static char hostnamebuf[80];
136 : char *rhost;
137 :
138 : #ifdef HAVE_IDN
139 : status = idna_to_ascii_lz (host, &rhost, 0);
140 : if (status)
141 : {
142 : error (0, 0, "%s: %s", host, idna_strerror (status));
143 : code = -1;
144 : return ((char *) 0);
145 : }
146 : #else /* !HAVE_IDN */
147 0 : rhost = strdup (host);
148 : #endif
149 :
150 0 : snprintf (portstr, sizeof (portstr) - 1, "%u", port);
151 0 : memset (&hisctladdr, 0, sizeof (hisctladdr));
152 0 : memset (&hints, 0, sizeof (hints));
153 :
154 0 : hints.ai_family = usefamily;
155 0 : hints.ai_socktype = SOCK_STREAM;
156 0 : hints.ai_flags = AI_CANONNAME;
157 : #ifdef AI_IDN
158 0 : hints.ai_flags |= AI_IDN;
159 : #endif
160 : #ifdef AI_CANONIDN
161 0 : hints.ai_flags |= AI_CANONIDN;
162 : #endif
163 :
164 0 : status = getaddrinfo (rhost, portstr, &hints, &res);
165 0 : if (status)
166 : {
167 0 : error (0, 0, "%s: %s", rhost, gai_strerror (status));
168 0 : code = -1;
169 0 : free (rhost);
170 0 : return ((char *) 0);
171 : }
172 :
173 0 : if (res->ai_canonname)
174 0 : strncpy (hostnamebuf, res->ai_canonname, sizeof (hostnamebuf));
175 : else
176 0 : strncpy (hostnamebuf, rhost, sizeof (hostnamebuf));
177 :
178 0 : hostname = hostnamebuf;
179 0 : free (rhost);
180 :
181 0 : for (ai = res; ai != NULL; ai = ai->ai_next, ++again)
182 : {
183 0 : if (again)
184 : {
185 0 : getnameinfo (ai->ai_addr, ai->ai_addrlen, ia, sizeof (ia),
186 : NULL, 0, NI_NUMERICHOST);
187 0 : error (0, 0, "Trying %s ...", ia);
188 : }
189 :
190 0 : s = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
191 0 : if (s < 0)
192 0 : continue;
193 :
194 0 : timeout.tv_sec = FTP_CONNECT_TIMEOUT;
195 0 : timeout.tv_usec = 0;
196 0 : if (setsockopt (s, SOL_SOCKET, SO_SNDTIMEO, &timeout,
197 0 : sizeof (timeout)) < 0 && debug)
198 0 : error (0, errno, "setsockopt (SO_SNDTIMEO)");
199 :
200 0 : if (connect (s, ai->ai_addr, ai->ai_addrlen) < 0)
201 : {
202 0 : int oerrno = (errno != EINPROGRESS) ? errno : ETIMEDOUT;
203 :
204 0 : getnameinfo (ai->ai_addr, ai->ai_addrlen, ia, sizeof (ia),
205 : NULL, 0, NI_NUMERICHOST);
206 0 : error (0, oerrno, "connect to address %s", ia);
207 0 : close (s);
208 0 : s = -1;
209 0 : continue;
210 : }
211 :
212 : /* A standing connection is found: register the address. */
213 0 : timeout.tv_sec = 0;
214 0 : timeout.tv_usec = 0;
215 0 : (void) setsockopt (s, SOL_SOCKET, SO_SNDTIMEO, &timeout,
216 : sizeof (timeout));
217 :
218 0 : ctladdrlen = ai->ai_addrlen;
219 0 : memmove ((caddr_t) &hisctladdr, ai->ai_addr, ai->ai_addrlen);
220 0 : break;
221 : } /* for (ai = ai->ai_next) */
222 :
223 0 : if (res)
224 0 : freeaddrinfo (res);
225 :
226 0 : if (ai == NULL)
227 : {
228 0 : error (0, 0, "no response from host");
229 0 : code = -1;
230 0 : goto bad;
231 : }
232 :
233 0 : len = sizeof (myctladdr);
234 0 : if (getsockname (s, (struct sockaddr *) &myctladdr, &len) < 0)
235 : {
236 0 : error (0, errno, "getsockname");
237 0 : code = -1;
238 0 : goto bad;
239 : }
240 :
241 : #if defined IP_TOS && defined IPPROTO_IP && defined IPTOS_LOWDELAY
242 0 : tos = IPTOS_LOWDELAY;
243 0 : if (myctladdr.ss_family == AF_INET &&
244 0 : setsockopt (s, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof (int)) < 0)
245 0 : error (0, errno, "setsockopt TOS (ignored)");
246 : #endif
247 :
248 0 : cin = fdopen (s, "r");
249 : /* dup(s) is for sake of stdio implementations who do not
250 : allow two fdopen's on the same file-descriptor */
251 0 : cout = fdopen (dup (s), "w");
252 0 : if (cin == NULL || cout == NULL)
253 : {
254 0 : error (0, 0, "fdopen failed.");
255 0 : if (cin)
256 0 : fclose (cin);
257 0 : if (cout)
258 0 : fclose (cout);
259 0 : code = -1;
260 0 : goto bad;
261 : }
262 0 : if (verbose)
263 0 : printf ("Connected to %s.\n", hostname);
264 0 : if (getreply (0) > 2)
265 : { /* read startup message from server */
266 0 : if (cin)
267 0 : fclose (cin);
268 0 : if (cout)
269 0 : fclose (cout);
270 0 : code = -1;
271 0 : goto bad;
272 : }
273 :
274 : #ifdef SO_OOBINLINE
275 : {
276 0 : int on = 1;
277 :
278 0 : if (setsockopt (s, SOL_SOCKET, SO_OOBINLINE, (char *) &on, sizeof (on))
279 0 : < 0 && debug)
280 : {
281 0 : error (0, errno, "setsockopt");
282 : }
283 : }
284 : #endif /* SO_OOBINLINE */
285 :
286 0 : return (hostname);
287 : bad:
288 0 : close (s);
289 0 : return ((char *) 0);
290 : }
291 :
292 : int
293 0 : login (char *host)
294 : {
295 : char tmp[80];
296 : char *user, *pass, *acct;
297 0 : int n, aflag = 0;
298 :
299 0 : user = pass = acct = 0;
300 0 : if (remote_userpass (host, &user, &pass, &acct) < 0)
301 : {
302 0 : code = -1;
303 0 : return (0);
304 : }
305 0 : while (user == NULL)
306 : {
307 0 : char *myname = getlogin ();
308 :
309 0 : if (myname == NULL)
310 : {
311 0 : struct passwd *pp = getpwuid (getuid ());
312 :
313 0 : if (pp != NULL)
314 0 : myname = pp->pw_name;
315 : }
316 0 : if (myname)
317 0 : printf ("Name (%s:%s): ", host, myname);
318 : else
319 0 : printf ("Name (%s): ", host);
320 0 : if (fgets (tmp, sizeof (tmp) - 1, stdin))
321 : {
322 : /* If the user presses return immediately, we get "\n".
323 : * In all other cases, the assignment is a no-op,
324 : * and is always well defined thanks to fgets().
325 : */
326 0 : tmp[strlen (tmp) - 1] = '\0';
327 : }
328 : else
329 0 : *tmp = '\0'; /* Ctrl-D received. */
330 0 : if (*tmp == '\0')
331 0 : user = myname;
332 : else
333 0 : user = tmp;
334 : }
335 0 : n = command ("USER %s", user);
336 0 : if (n == CONTINUE)
337 : {
338 : /* Is this a case of challenge-response?
339 : * RFC 2228 stipulates code 336 for this.
340 : * Suppress the message in verbose mode,
341 : * since it has already been displayed.
342 : */
343 0 : if (code == 336 && !verbose)
344 0 : printf ("%s\n", reply_string + strlen ("336 "));
345 : /* In addition, any password given on the
346 : * command line is irrelevant, so ignore it.
347 : */
348 0 : if (pass == NULL || code == 336)
349 0 : pass = getpass ("Password: ");
350 0 : n = command ("PASS %s", pass);
351 0 : if (pass)
352 0 : memset (pass, 0, strlen (pass));
353 : }
354 0 : if (n == CONTINUE)
355 : {
356 0 : aflag++;
357 0 : acct = getpass ("Account: ");
358 0 : n = command ("ACCT %s", acct);
359 0 : if (acct)
360 0 : memset (acct, 0, strlen (acct));
361 : }
362 0 : if (n != COMPLETE)
363 : {
364 0 : error (0, 0, "Login failed.");
365 0 : return (0);
366 : }
367 0 : if (!aflag && acct != NULL)
368 : {
369 0 : command ("ACCT %s", acct);
370 0 : memset (acct, 0, strlen (acct));
371 : }
372 0 : if (proxy)
373 0 : return (1);
374 0 : for (n = 0; n < macnum; ++n)
375 : {
376 0 : if (!strcmp ("init", macros[n].mac_name))
377 : {
378 0 : free (line);
379 0 : line = calloc (MAXLINE, sizeof (*line));
380 0 : linelen = MAXLINE;
381 0 : if (!line)
382 0 : quit (0, 0);
383 :
384 : /* Simulate input of the macro 'init'. */
385 0 : strcpy (line, "$init");
386 0 : makeargv ();
387 0 : domacro (margc, margv);
388 0 : break;
389 : }
390 : }
391 0 : return (1);
392 : }
393 :
394 : void
395 0 : cmdabort (int sig _GL_UNUSED_PARAMETER)
396 : {
397 :
398 0 : printf ("\n");
399 0 : fflush (stdout);
400 0 : abrtflag++;
401 0 : if (ptflag)
402 0 : longjmp (ptabort, 1);
403 0 : }
404 :
405 : int
406 0 : command (const char *fmt, ...)
407 : {
408 : va_list ap;
409 : int r;
410 : sighandler_t oldintr;
411 :
412 0 : abrtflag = 0;
413 0 : if (debug)
414 : {
415 0 : printf ("---> ");
416 0 : va_start (ap, fmt);
417 0 : if (strncmp ("PASS ", fmt, 5) == 0)
418 0 : printf ("PASS XXXX");
419 0 : else if (strncmp ("ACCT ", fmt, 5) == 0)
420 0 : printf ("ACCT XXXX");
421 : else
422 0 : vfprintf (stdout, fmt, ap);
423 0 : va_end (ap);
424 0 : printf ("\n");
425 0 : fflush (stdout);
426 : }
427 0 : if (cout == NULL)
428 : {
429 0 : error (0, 0, "No control connection for command");
430 0 : code = -1;
431 0 : return (0);
432 : }
433 0 : oldintr = signal (SIGINT, cmdabort);
434 : /* Under weird circumstances, we get a SIGPIPE from fflush(). */
435 0 : signal (SIGPIPE, SIG_IGN);
436 0 : va_start (ap, fmt);
437 0 : vfprintf (cout, fmt, ap);
438 0 : va_end (ap);
439 0 : fprintf (cout, "\r\n");
440 0 : fflush (cout);
441 0 : cpend = 1;
442 0 : r = getreply (!strcmp (fmt, "QUIT"));
443 0 : if (abrtflag && oldintr != SIG_IGN)
444 0 : (*oldintr) (SIGINT);
445 0 : signal (SIGINT, oldintr);
446 0 : signal (SIGPIPE, SIG_DFL);
447 0 : return (r);
448 : }
449 :
450 : char reply_string[BUFSIZ]; /* last line of previous reply */
451 :
452 : int
453 0 : getreply (int expecteof)
454 : {
455 : int c, n;
456 : int dig;
457 0 : int originalcode = 0, continuation = 0;
458 : sighandler_t oldintr;
459 0 : int pflag = 0;
460 0 : char *cp, *pt = pasv;
461 :
462 0 : oldintr = signal (SIGINT, cmdabort);
463 : for (;;)
464 : {
465 0 : dig = n = code = 0;
466 0 : cp = reply_string;
467 0 : while ((c = getc (cin)) != '\n')
468 : {
469 0 : if (c == IAC)
470 : { /* handle telnet commands */
471 0 : switch (c = getc (cin))
472 : {
473 : case WILL:
474 : case WONT:
475 0 : c = getc (cin);
476 0 : fprintf (cout, "%c%c%c", IAC, DONT, c);
477 0 : fflush (cout);
478 0 : break;
479 : case DO:
480 : case DONT:
481 0 : c = getc (cin);
482 0 : fprintf (cout, "%c%c%c", IAC, WONT, c);
483 0 : fflush (cout);
484 0 : break;
485 : default:
486 0 : break;
487 : }
488 0 : continue;
489 : }
490 0 : dig++;
491 0 : if (c == EOF)
492 : {
493 0 : if (expecteof)
494 : {
495 0 : signal (SIGINT, oldintr);
496 0 : code = 221;
497 0 : return (0);
498 : }
499 0 : lostpeer (0);
500 0 : if (verbose)
501 : {
502 0 : printf
503 : ("421 Service not available, remote server has closed connection\n");
504 0 : fflush (stdout);
505 : }
506 0 : code = 421;
507 0 : return (TRANSIENT);
508 : }
509 0 : if (c != '\r' && (verbose > 0 ||
510 0 : (verbose > -1 && n == ERROR && dig > 4)))
511 : {
512 0 : if (proxflag && (dig == 1 || (dig == 5 && verbose == 0)))
513 0 : printf ("%s:", hostname);
514 0 : putchar (c);
515 : }
516 0 : if (dig < 4 && isdigit (c))
517 0 : code = code * 10 + (c - '0');
518 0 : if (!pflag && (code == 227 || code == 228 || code == 229)) /* PASV || LPSV || EPSV */
519 0 : pflag = 1;
520 0 : if (dig > 4 && pflag == 1 && isdigit (c))
521 0 : pflag = 2;
522 0 : if (pflag == 2)
523 : {
524 0 : if (c != '\r' && c != ')')
525 0 : *pt++ = c;
526 : else
527 : {
528 0 : *pt = '\0';
529 0 : pflag = 3;
530 : }
531 : }
532 0 : if (dig == 4 && c == '-')
533 : {
534 0 : if (continuation)
535 0 : code = 0;
536 0 : continuation++;
537 : }
538 0 : if (n == 0)
539 0 : n = c - '0'; /* Extract ARPA's reply code. */
540 0 : if (cp < &reply_string[sizeof (reply_string) - 1])
541 0 : *cp++ = c;
542 : }
543 0 : if (verbose > 0 || (verbose > -1 && n == ERROR))
544 : {
545 0 : putchar (c);
546 0 : fflush (stdout);
547 : }
548 0 : if (continuation && code != originalcode)
549 : {
550 0 : if (originalcode == 0)
551 0 : originalcode = code;
552 0 : continue;
553 : }
554 0 : *cp = '\0';
555 0 : if (n != PRELIM)
556 0 : cpend = 0;
557 0 : signal (SIGINT, oldintr);
558 0 : if (code == 421 || originalcode == 421)
559 0 : lostpeer (0);
560 0 : if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
561 0 : (*oldintr) (SIGINT);
562 0 : return n;
563 0 : }
564 : }
565 :
566 : int
567 0 : empty (fd_set *mask, int sec)
568 : {
569 : struct timeval t;
570 :
571 0 : t.tv_sec = (long) sec;
572 0 : t.tv_usec = 0;
573 0 : return (select (32, mask, (fd_set *) 0, (fd_set *) 0, &t));
574 : }
575 :
576 : jmp_buf sendabort;
577 :
578 : void
579 0 : abortsend (int sig _GL_UNUSED_PARAMETER)
580 : {
581 :
582 0 : mflag = 0;
583 0 : abrtflag = 0;
584 0 : printf ("\nsend aborted\nwaiting for remote to finish abort\n");
585 0 : fflush (stdout);
586 0 : longjmp (sendabort, 1);
587 : }
588 :
589 : void
590 0 : sendrequest (char *cmd, char *local, char *remote, int printnames)
591 : {
592 : struct stat st;
593 : struct timeval start, stop;
594 : int c, d;
595 0 : FILE *fin, *dout = 0, *popen (const char *, const char *);
596 : int (*closefunc) (FILE *);
597 : sighandler_t oldintr, oldintp;
598 0 : long long bytes = 0, local_hashbytes = hashbytes;
599 : char *lmode, *bufp;
600 0 : int blksize = BUFSIZ;
601 : static int bufsize = 0;
602 : static char *buf;
603 :
604 0 : if (verbose && printnames)
605 : {
606 0 : if (local && *local != '-')
607 0 : printf ("local: %s ", local);
608 0 : if (remote)
609 0 : printf ("remote: %s\n", remote);
610 : }
611 0 : if (proxy)
612 : {
613 0 : proxtrans (cmd, local, remote);
614 0 : return;
615 : }
616 0 : if (curtype != type)
617 0 : changetype (type, 0);
618 0 : closefunc = NULL;
619 0 : oldintr = NULL;
620 0 : oldintp = NULL;
621 0 : lmode = "w";
622 0 : if (setjmp (sendabort))
623 : {
624 0 : while (cpend)
625 : {
626 0 : getreply (0);
627 : }
628 0 : if (data >= 0)
629 : {
630 0 : close (data);
631 0 : data = -1;
632 : }
633 0 : if (oldintr)
634 0 : signal (SIGINT, oldintr);
635 0 : if (oldintp)
636 0 : signal (SIGPIPE, oldintp);
637 0 : code = -1;
638 0 : return;
639 : }
640 0 : oldintr = signal (SIGINT, abortsend);
641 0 : if (strcmp (local, "-") == 0)
642 0 : fin = stdin;
643 0 : else if (*local == '|')
644 : {
645 0 : oldintp = signal (SIGPIPE, SIG_IGN);
646 0 : fin = popen (local + 1, "r");
647 0 : if (fin == NULL)
648 : {
649 0 : error (0, errno, "%s", local + 1);
650 0 : signal (SIGINT, oldintr);
651 0 : signal (SIGPIPE, oldintp);
652 0 : code = -1;
653 0 : return;
654 : }
655 0 : closefunc = pclose;
656 : }
657 : else
658 : {
659 0 : fin = fopen (local, "r");
660 0 : if (fin == NULL)
661 : {
662 0 : error (0, errno, "local: %s", local);
663 0 : signal (SIGINT, oldintr);
664 0 : code = -1;
665 0 : return;
666 : }
667 0 : closefunc = fclose;
668 0 : if (fstat (fileno (fin), &st) < 0 || (st.st_mode & S_IFMT) != S_IFREG)
669 : {
670 0 : fprintf (stdout, "%s: not a plain file.\n", local);
671 0 : signal (SIGINT, oldintr);
672 0 : fclose (fin);
673 0 : code = -1;
674 0 : return;
675 : }
676 0 : blksize = st.st_blksize;
677 : }
678 0 : if (initconn ())
679 : {
680 0 : signal (SIGINT, oldintr);
681 0 : if (oldintp)
682 0 : signal (SIGPIPE, oldintp);
683 0 : code = -1;
684 0 : if (closefunc != NULL)
685 0 : (*closefunc) (fin);
686 0 : return;
687 : }
688 0 : if (setjmp (sendabort))
689 0 : goto abort;
690 :
691 0 : if (restart_point &&
692 0 : (strcmp (cmd, "STOR") == 0 || strcmp (cmd, "APPE") == 0))
693 : {
694 : off_t rc;
695 :
696 0 : switch (curtype)
697 : {
698 : case TYPE_A:
699 0 : rc = fseeko (fin, restart_point, SEEK_SET);
700 0 : break;
701 : case TYPE_I:
702 : case TYPE_L:
703 0 : rc = lseek (fileno (fin), restart_point, SEEK_SET);
704 0 : break;
705 : }
706 0 : if (rc < 0)
707 : {
708 0 : (void) command ("ABOR");
709 0 : getreply (0);
710 0 : error (0, errno, "local: %s", local);
711 0 : restart_point = 0;
712 0 : if (closefunc != NULL)
713 0 : (*closefunc) (fin);
714 0 : return;
715 : }
716 0 : if (command ("REST %jd", (intmax_t) restart_point) != CONTINUE)
717 : {
718 0 : restart_point = 0;
719 0 : if (closefunc != NULL)
720 0 : (*closefunc) (fin);
721 0 : return;
722 : }
723 0 : restart_point = 0;
724 0 : lmode = "r+w";
725 : }
726 0 : if (remote)
727 : {
728 0 : if (command ("%s %s", cmd, remote) != PRELIM)
729 : {
730 0 : signal (SIGINT, oldintr);
731 0 : if (oldintp)
732 0 : signal (SIGPIPE, oldintp);
733 0 : if (closefunc != NULL)
734 0 : (*closefunc) (fin);
735 0 : return;
736 : }
737 : }
738 0 : else if (command ("%s", cmd) != PRELIM)
739 : {
740 0 : signal (SIGINT, oldintr);
741 0 : if (oldintp)
742 0 : signal (SIGPIPE, oldintp);
743 0 : if (closefunc != NULL)
744 0 : (*closefunc) (fin);
745 0 : return;
746 : }
747 0 : dout = dataconn (lmode);
748 0 : if (dout == NULL)
749 0 : goto abort;
750 :
751 0 : if (blksize > bufsize)
752 : {
753 0 : free (buf);
754 0 : buf = malloc ((unsigned) blksize);
755 0 : if (buf == NULL)
756 : {
757 0 : error (0, errno, "malloc");
758 0 : bufsize = 0;
759 0 : goto abort;
760 : }
761 0 : bufsize = blksize;
762 : }
763 :
764 0 : gettimeofday (&start, (struct timezone *) 0);
765 0 : oldintp = signal (SIGPIPE, SIG_IGN);
766 0 : switch (curtype)
767 : {
768 :
769 : case TYPE_I:
770 : case TYPE_L:
771 0 : errno = d = 0;
772 0 : while ((c = read (fileno (fin), buf, bufsize)) > 0)
773 : {
774 0 : bytes += c;
775 0 : for (bufp = buf; c > 0; c -= d, bufp += d)
776 0 : if ((d = write (fileno (dout), bufp, c)) <= 0)
777 0 : break;
778 0 : if (hash)
779 : {
780 0 : while (bytes >= local_hashbytes)
781 : {
782 0 : putchar ('#');
783 0 : local_hashbytes += hashbytes;
784 : }
785 0 : fflush (stdout);
786 : }
787 : }
788 0 : if (hash && bytes > 0)
789 : {
790 0 : if (bytes < local_hashbytes)
791 0 : putchar ('#');
792 0 : putchar ('\n');
793 0 : fflush (stdout);
794 : }
795 0 : if (c < 0)
796 0 : error (0, errno, "local: %s", local);
797 0 : if (d < 0)
798 : {
799 0 : if (errno != EPIPE)
800 0 : error (0, errno, "netout");
801 0 : bytes = -1;
802 : }
803 0 : break;
804 :
805 : case TYPE_A:
806 0 : while ((c = getc (fin)) != EOF)
807 : {
808 0 : if (c == '\n')
809 : {
810 0 : while (hash && (bytes >= local_hashbytes))
811 : {
812 0 : putchar ('#');
813 0 : fflush (stdout);
814 0 : local_hashbytes += hashbytes;
815 : }
816 0 : if (ferror (dout))
817 0 : break;
818 0 : putc ('\r', dout);
819 0 : bytes++;
820 : }
821 0 : putc (c, dout);
822 0 : bytes++;
823 : /* if (c == '\r') { */
824 : /* putc('\0', dout); // this violates rfc */
825 : /* bytes++; */
826 : /* } */
827 : }
828 0 : if (hash)
829 : {
830 0 : if (bytes < local_hashbytes)
831 0 : putchar ('#');
832 0 : putchar ('\n');
833 0 : fflush (stdout);
834 : }
835 0 : if (ferror (fin))
836 0 : error (0, errno, "local: %s", local);
837 0 : if (ferror (dout))
838 : {
839 0 : if (errno != EPIPE)
840 0 : error (0, errno, "netout");
841 0 : bytes = -1;
842 : }
843 0 : break;
844 : }
845 0 : if (closefunc != NULL)
846 0 : (*closefunc) (fin);
847 0 : fclose (dout);
848 0 : gettimeofday (&stop, (struct timezone *) 0);
849 0 : getreply (0);
850 0 : signal (SIGINT, oldintr);
851 0 : if (oldintp)
852 0 : signal (SIGPIPE, oldintp);
853 0 : if (bytes > 0)
854 0 : ptransfer ("sent", bytes, &start, &stop);
855 0 : return;
856 : abort:
857 0 : signal (SIGINT, oldintr);
858 0 : if (oldintp)
859 0 : signal (SIGPIPE, oldintp);
860 0 : if (!cpend)
861 : {
862 0 : code = -1;
863 0 : return;
864 : }
865 0 : if (data >= 0)
866 : {
867 0 : close (data);
868 0 : data = -1;
869 : }
870 0 : if (dout)
871 0 : fclose (dout);
872 0 : getreply (0);
873 0 : code = -1;
874 0 : if (closefunc != NULL && fin != NULL)
875 0 : (*closefunc) (fin);
876 0 : gettimeofday (&stop, (struct timezone *) 0);
877 0 : if (bytes > 0)
878 0 : ptransfer ("sent", bytes, &start, &stop);
879 : }
880 :
881 : jmp_buf recvabort;
882 :
883 : void
884 0 : abortrecv (int sig _GL_UNUSED_PARAMETER)
885 : {
886 :
887 0 : mflag = 0;
888 0 : abrtflag = 0;
889 0 : printf ("\nreceive aborted\nwaiting for remote to finish abort\n");
890 0 : fflush (stdout);
891 0 : longjmp (recvabort, 1);
892 : }
893 :
894 : void
895 0 : recvrequest (char *cmd, char *local, char *remote, char *lmode, int printnames)
896 : {
897 0 : FILE *fout, *din = 0;
898 : int (*closefunc) (FILE *);
899 : sighandler_t oldintr, oldintp;
900 0 : int c, d, is_retr, tcrflag, bare_lfs = 0;
901 0 : int blksize = BUFSIZ;
902 : static int bufsize = 0;
903 : static char *buf;
904 0 : long long bytes = 0, local_hashbytes = hashbytes;
905 : struct timeval start, stop;
906 :
907 0 : is_retr = strcmp (cmd, "RETR") == 0;
908 0 : if (is_retr && verbose && printnames)
909 : {
910 0 : if (local && *local != '-')
911 0 : printf ("local: %s ", local);
912 0 : if (remote)
913 0 : printf ("remote: %s\n", remote);
914 : }
915 0 : if (proxy && is_retr)
916 : {
917 0 : proxtrans (cmd, local, remote);
918 0 : return;
919 : }
920 0 : closefunc = NULL;
921 0 : oldintr = NULL;
922 0 : oldintp = NULL;
923 0 : tcrflag = !crflag && is_retr;
924 0 : if (setjmp (recvabort))
925 : {
926 0 : while (cpend)
927 : {
928 0 : getreply (0);
929 : }
930 0 : if (data >= 0)
931 : {
932 0 : close (data);
933 0 : data = -1;
934 : }
935 0 : if (oldintr)
936 0 : signal (SIGINT, oldintr);
937 0 : code = -1;
938 0 : return;
939 : }
940 0 : oldintr = signal (SIGINT, abortrecv);
941 0 : if (strcmp (local, "-") && *local != '|')
942 : {
943 0 : if (runique && (local = gunique (local)) == NULL)
944 : {
945 0 : signal (SIGINT, oldintr);
946 0 : code = -1;
947 0 : return;
948 : }
949 : }
950 0 : if (!is_retr)
951 : {
952 0 : if (curtype != TYPE_A)
953 0 : changetype (TYPE_A, 0);
954 : }
955 0 : else if (curtype != type)
956 0 : changetype (type, 0);
957 0 : if (initconn ())
958 : {
959 0 : signal (SIGINT, oldintr);
960 0 : code = -1;
961 0 : return;
962 : }
963 0 : if (setjmp (recvabort))
964 0 : goto abort;
965 0 : if (is_retr && restart_point &&
966 0 : command ("REST %jd", (intmax_t) restart_point) != CONTINUE)
967 0 : return;
968 0 : if (remote)
969 : {
970 0 : if (command ("%s %s", cmd, remote) != PRELIM)
971 : {
972 0 : signal (SIGINT, oldintr);
973 0 : return;
974 : }
975 : }
976 : else
977 : {
978 0 : if (command ("%s", cmd) != PRELIM)
979 : {
980 0 : signal (SIGINT, oldintr);
981 0 : return;
982 : }
983 : }
984 0 : din = dataconn ("r");
985 0 : if (din == NULL)
986 0 : goto abort;
987 :
988 0 : if (strcmp (local, "-") == 0)
989 0 : fout = stdout;
990 0 : else if (*local == '|')
991 : {
992 0 : oldintp = signal (SIGPIPE, SIG_IGN);
993 0 : fout = popen (local + 1, "w");
994 0 : if (fout == NULL)
995 : {
996 0 : error (0, errno, "%s", local + 1);
997 0 : goto abort;
998 : }
999 0 : closefunc = pclose;
1000 : }
1001 : else
1002 : {
1003 : struct stat st;
1004 :
1005 0 : fout = fopen (local, lmode);
1006 0 : if (fout == NULL || fstat (fileno (fout), &st) < 0)
1007 : {
1008 0 : error (0, errno, "local: %s", local);
1009 0 : goto abort;
1010 : }
1011 0 : closefunc = fclose;
1012 0 : blksize = st.st_blksize;
1013 : }
1014 :
1015 0 : if (blksize > bufsize)
1016 : {
1017 0 : free (buf);
1018 0 : buf = malloc ((unsigned) blksize);
1019 0 : if (buf == NULL)
1020 : {
1021 0 : error (0, errno, "malloc");
1022 0 : bufsize = 0;
1023 0 : goto abort;
1024 : }
1025 0 : bufsize = blksize;
1026 : }
1027 :
1028 0 : gettimeofday (&start, (struct timezone *) 0);
1029 0 : switch (curtype)
1030 : {
1031 :
1032 : case TYPE_I:
1033 : case TYPE_L:
1034 0 : if (restart_point && lseek (fileno (fout), restart_point, SEEK_SET) < 0)
1035 : {
1036 0 : error (0, errno, "local: %s", local);
1037 0 : if (closefunc != NULL)
1038 0 : (*closefunc) (fout);
1039 0 : return;
1040 : }
1041 0 : errno = d = 0;
1042 0 : while ((c = read (fileno (din), buf, bufsize)) > 0)
1043 : {
1044 0 : if ((d = write (fileno (fout), buf, c)) != c)
1045 0 : break;
1046 0 : bytes += c;
1047 0 : if (hash)
1048 : {
1049 0 : while (bytes >= local_hashbytes)
1050 : {
1051 0 : putchar ('#');
1052 0 : local_hashbytes += hashbytes;
1053 : }
1054 0 : fflush (stdout);
1055 : }
1056 : }
1057 :
1058 0 : if (hash && bytes > 0)
1059 : {
1060 0 : if (bytes < local_hashbytes)
1061 0 : putchar ('#');
1062 0 : putchar ('\n');
1063 0 : fflush (stdout);
1064 : }
1065 0 : if (c < 0)
1066 : {
1067 0 : if (errno != EPIPE)
1068 0 : error (0, errno, "netin");
1069 0 : bytes = -1;
1070 : }
1071 0 : if (d < c)
1072 : {
1073 0 : if (d < 0)
1074 0 : error (0, errno, "local: %s", local);
1075 : else
1076 0 : error (0, 0, "%s: short write", local);
1077 : }
1078 0 : break;
1079 :
1080 : case TYPE_A:
1081 0 : if (restart_point)
1082 : {
1083 : off_t i, n;
1084 : int ch;
1085 :
1086 0 : errno = 0;
1087 :
1088 0 : if (fseeko (fout, 0L, SEEK_SET) < 0)
1089 0 : goto done;
1090 0 : n = restart_point;
1091 0 : for (i = 0; i++ < n;)
1092 : {
1093 0 : if ((ch = getc (fout)) == EOF)
1094 0 : goto done;
1095 0 : if (ch == '\n')
1096 0 : i++;
1097 : }
1098 0 : if (fseeko (fout, 0L, SEEK_CUR) < 0)
1099 : {
1100 : done:
1101 : /* Cancel server's action quickly. */
1102 0 : (void) command ("ABOR");
1103 0 : getreply (0);
1104 :
1105 : /* Explain our failure. */
1106 0 : if (ch == EOF)
1107 0 : printf ("Action not taken: offset %jd is outside of %s.\n",
1108 : restart_point, local);
1109 : else
1110 0 : error (0, errno, "local: %s", local);
1111 :
1112 0 : if (closefunc != NULL)
1113 0 : (*closefunc) (fout);
1114 0 : return;
1115 : }
1116 : }
1117 0 : while ((c = getc (din)) != EOF)
1118 : {
1119 0 : if (c == '\n')
1120 0 : bare_lfs++;
1121 0 : while (c == '\r')
1122 : {
1123 0 : while (hash && (bytes >= local_hashbytes))
1124 : {
1125 0 : putchar ('#');
1126 0 : fflush (stdout);
1127 0 : local_hashbytes += hashbytes;
1128 : }
1129 0 : bytes++;
1130 0 : if ((c = getc (din)) != '\n' || tcrflag)
1131 : {
1132 0 : if (ferror (fout))
1133 0 : goto break2;
1134 0 : putc ('\r', fout);
1135 0 : if (c == '\0')
1136 : {
1137 0 : bytes++;
1138 0 : goto contin2;
1139 : }
1140 0 : if (c == EOF)
1141 0 : goto contin2;
1142 : }
1143 : }
1144 0 : putc (c, fout);
1145 0 : bytes++;
1146 : contin2:;
1147 : }
1148 : break2:
1149 0 : if (bare_lfs)
1150 : {
1151 0 : printf ("WARNING! %d bare linefeeds received in ASCII mode\n",
1152 : bare_lfs);
1153 0 : printf ("File may not have transferred correctly.\n");
1154 : }
1155 0 : if (hash)
1156 : {
1157 0 : if (bytes < local_hashbytes)
1158 0 : putchar ('#');
1159 0 : putchar ('\n');
1160 0 : fflush (stdout);
1161 : }
1162 0 : if (ferror (din))
1163 : {
1164 0 : if (errno != EPIPE)
1165 0 : error (0, errno, "netin");
1166 0 : bytes = -1;
1167 : }
1168 0 : if (ferror (fout))
1169 0 : error (0, errno, "local: %s", local);
1170 0 : break;
1171 : }
1172 0 : if (closefunc != NULL)
1173 0 : (*closefunc) (fout);
1174 0 : signal (SIGINT, oldintr);
1175 0 : if (oldintp)
1176 0 : signal (SIGPIPE, oldintp);
1177 0 : fclose (din);
1178 0 : gettimeofday (&stop, (struct timezone *) 0);
1179 0 : getreply (0);
1180 0 : if (bytes > 0 && is_retr)
1181 0 : ptransfer ("received", bytes, &start, &stop);
1182 0 : return;
1183 : abort:
1184 :
1185 : /* abort using RFC959 recommended IP,SYNC sequence */
1186 :
1187 0 : if (oldintp)
1188 0 : signal (SIGPIPE, oldintr);
1189 0 : signal (SIGINT, SIG_IGN);
1190 0 : if (!cpend)
1191 : {
1192 0 : code = -1;
1193 0 : signal (SIGINT, oldintr);
1194 0 : return;
1195 : }
1196 :
1197 0 : abort_remote (din);
1198 0 : code = -1;
1199 0 : if (data >= 0)
1200 : {
1201 0 : close (data);
1202 0 : data = -1;
1203 : }
1204 0 : if (closefunc != NULL && fout != NULL)
1205 0 : (*closefunc) (fout);
1206 0 : if (din)
1207 0 : fclose (din);
1208 0 : gettimeofday (&stop, (struct timezone *) 0);
1209 0 : if (bytes > 0)
1210 0 : ptransfer ("received", bytes, &start, &stop);
1211 0 : signal (SIGINT, oldintr);
1212 : }
1213 :
1214 : /*
1215 : * Need to start a listen on the data channel before we send the command,
1216 : * otherwise the server's connect may fail.
1217 : */
1218 : int
1219 0 : initconn (void)
1220 : {
1221 0 : char *p = NULL, *a = NULL;
1222 0 : int result, tmpno = 0;
1223 0 : int good_epsv = 0, good_lpsv = 0, j;
1224 : socklen_t len;
1225 0 : int on = 1;
1226 : uint32_t a0, a1, a2, a3, p0, p1, port;
1227 : uint32_t af, hal, h[16], pal; /* RFC 1639: LPSV resonse. */
1228 0 : struct sockaddr_in *data_addr_sa4 = (struct sockaddr_in *) &data_addr;
1229 0 : struct sockaddr_in6 *data_addr_sa6 = (struct sockaddr_in6 *) &data_addr;
1230 :
1231 0 : if (passivemode)
1232 : {
1233 0 : data = socket (myctladdr.ss_family, SOCK_STREAM, 0);
1234 0 : if (data < 0)
1235 : {
1236 0 : perror ("ftp: socket");
1237 0 : return (1);
1238 : }
1239 0 : if ((options & SO_DEBUG) &&
1240 0 : setsockopt (data, SOL_SOCKET, SO_DEBUG, (char *) &on,
1241 : sizeof (on)) < 0)
1242 0 : if (errno != EACCES) /* Ignore insufficient permission. */
1243 0 : error (0, errno, "setsockopt DEBUG (ignored)");
1244 :
1245 : /* Be contemporary:
1246 : * first try EPSV,
1247 : * then fall back to PASV/LPSV.
1248 : */
1249 0 : switch (myctladdr.ss_family)
1250 : {
1251 : case AF_INET:
1252 0 : if (doepsv4 && command ("EPSV") == COMPLETE)
1253 : {
1254 0 : good_epsv = 1;
1255 0 : break;
1256 : }
1257 0 : if (doepsv4)
1258 : {
1259 : /* When arriving here, EPSV failed. Prevent new attempts. */
1260 0 : doepsv4 = 0;
1261 : }
1262 0 : if (command ("PASV") == COMPLETE)
1263 0 : break;
1264 0 : if (command ("LPSV") == COMPLETE)
1265 : {
1266 0 : good_lpsv = 1;
1267 0 : break;
1268 : }
1269 0 : printf ("Passive mode refused.\n");
1270 0 : goto bad;
1271 : break;
1272 : case AF_INET6:
1273 0 : if (command ("EPSV") == COMPLETE)
1274 : {
1275 0 : good_epsv = 1;
1276 0 : break;
1277 : }
1278 0 : if (command ("LPSV") == COMPLETE)
1279 : {
1280 0 : good_lpsv = 1;
1281 0 : break;
1282 : }
1283 0 : printf ("Passive mode refused.\n");
1284 0 : goto bad;
1285 : break;
1286 : }
1287 :
1288 0 : if (good_epsv)
1289 : {
1290 : /* EPSV: IPv4 or IPv6
1291 : *
1292 : * Expected response (perl): pasv =~ '%u|'
1293 : * This communicates a port number.
1294 : */
1295 0 : if (sscanf (pasv, "%u|", &port) != 1)
1296 : {
1297 0 : printf ("Extended passive mode scan failure. "
1298 : "Should not happen!\n");
1299 0 : (void) command ("ABOR"); /* Cancel any open connection. */
1300 0 : goto bad;
1301 : }
1302 0 : data_addr = hisctladdr;
1303 0 : switch (data_addr.ss_family)
1304 : {
1305 : case AF_INET:
1306 0 : data_addr_sa4->sin_port = htons (port);
1307 0 : break;
1308 : case AF_INET6:
1309 0 : data_addr_sa6->sin6_port = htons (port);
1310 0 : break;
1311 : }
1312 : } /* EPSV */
1313 0 : else if (good_lpsv)
1314 : {
1315 : /* LPSV: IPv4 or IPv6
1316 : *
1317 : * At this point we have got a string of comma
1318 : * separated, one-byte unsigned integer values.
1319 : * Length and interpretation depends on address
1320 : * family.
1321 : */
1322 :
1323 0 : if (myctladdr.ss_family == AF_INET)
1324 : {
1325 0 : if ((sscanf (pasv, "%u," /* af */
1326 : "%u,%u,%u,%u,%u," /* hal, h[4] */
1327 : "%u,%u,%u", /* pal, p0, p1 */
1328 : &af, &hal, &h[0], &h[1], &h[2], &h[3], &pal, &p0, &p1) != 9)
1329 0 : || (/* Strong checking */ af != 4 || hal != 4 || pal != 2) )
1330 : {
1331 0 : printf ("Passive mode address scan failure. "
1332 : "Shouldn't happen!\n");
1333 0 : (void) command ("ABOR"); /* Cancel any open connection. */
1334 0 : goto bad;
1335 : }
1336 0 : for (j = 0; j < 4; ++j)
1337 0 : h[j] &= 0xff; /* Mask only the significant bits. */
1338 :
1339 0 : data_addr.ss_family = AF_INET;
1340 0 : data_addr_sa4->sin_port =
1341 0 : htons (((p0 & 0xff) << 8) | (p1 & 0xff));
1342 :
1343 : {
1344 0 : uint32_t *pu32 = (uint32_t *) &data_addr_sa4->sin_addr.s_addr;
1345 0 : pu32[0] = htonl ( (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | h[3]);
1346 : }
1347 : } /* LPSV IPv4 */
1348 : else /* IPv6 */
1349 : {
1350 0 : if ((sscanf (pasv, "%u," /* af */
1351 : "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u," /* hal, h[16] */
1352 : "%u,%u,%u", /* pal, p0, p1 */
1353 : &af, &hal, &h[0], &h[1], &h[2], &h[3], &h[4], &h[5], &h[6], &h[7],
1354 : &h[8], &h[9], &h[10], &h[11], &h[12], &h[13], &h[14], &h[15],
1355 : &pal, &p0, &p1) != 21)
1356 0 : || (/* Strong checking */ af != 6 || hal != 16 || pal != 2) )
1357 : {
1358 0 : printf ("Passive mode address scan failure. "
1359 : "Shouldn't happen!\n");
1360 0 : (void) command ("ABOR"); /* Cancel any open connection. */
1361 0 : goto bad;
1362 : }
1363 0 : for (j = 0; j < 16; ++j)
1364 0 : h[j] &= 0xff; /* Mask only the significant bits. */
1365 :
1366 0 : data_addr.ss_family = AF_INET6;
1367 0 : data_addr_sa6->sin6_port =
1368 0 : htons (((p0 & 0xff) << 8) | (p1 & 0xff));
1369 :
1370 : {
1371 0 : uint32_t *pu32 = (uint32_t *) &data_addr_sa6->sin6_addr.s6_addr;
1372 0 : pu32[0] = htonl ( (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | h[3]);
1373 0 : pu32[1] = htonl ( (h[4] << 24) | (h[5] << 16) | (h[6] << 8) | h[7]);
1374 0 : pu32[2] = htonl ( (h[8] << 24) | (h[9] << 16) | (h[10] << 8) | h[11]);
1375 0 : pu32[3] = htonl ( (h[12] << 24) | (h[13] << 16) | (h[14] << 8) | h[15]);
1376 : }
1377 : } /* LPSV IPv6 */
1378 : }
1379 : else /* !EPSV && !LPSV */
1380 : { /* PASV */
1381 0 : if (myctladdr.ss_family == AF_INET)
1382 : { /* PASV */
1383 0 : if (sscanf (pasv, "%u,%u,%u,%u,%u,%u",
1384 : &a0, &a1, &a2, &a3, &p0, &p1) != 6)
1385 : {
1386 0 : printf ("Passive mode address scan failure. "
1387 : "Shouldn't happen!\n");
1388 0 : (void) command ("ABOR"); /* Cancel any open connection. */
1389 0 : goto bad;
1390 : }
1391 0 : data_addr.ss_family = AF_INET;
1392 0 : data_addr_sa4->sin_addr.s_addr =
1393 0 : htonl ( (a0 << 24) | ((a1 & 0xff) << 16)
1394 0 : | ((a2 & 0xff) << 8) | (a3 & 0xff) );
1395 0 : data_addr_sa4->sin_port =
1396 0 : htons (((p0 & 0xff) << 8) | (p1 & 0xff));
1397 : } /* PASV */
1398 : else
1399 : {
1400 : /* Catch all impossible cases. */
1401 0 : printf ("Passive mode address scan failure. Shouldn't happen!\n");
1402 0 : goto bad;
1403 : }
1404 : } /* PASV */
1405 :
1406 0 : if (connect (data, (struct sockaddr *) &data_addr, ctladdrlen) < 0)
1407 : {
1408 0 : perror ("ftp: connect");
1409 0 : goto bad;
1410 : }
1411 : #if defined IP_TOS && defined IPPROTO_IP && defined IPTOS_THROUGHPUT
1412 0 : on = IPTOS_THROUGHPUT;
1413 0 : if (data_addr.ss_family == AF_INET &&
1414 0 : setsockopt (data, IPPROTO_IP, IP_TOS, (char *) &on,
1415 : sizeof (int)) < 0)
1416 0 : perror ("ftp: setsockopt TOS (ignored)");
1417 : #endif
1418 0 : return (0);
1419 : }
1420 :
1421 : noport:
1422 0 : data_addr = myctladdr;
1423 0 : if (sendport)
1424 : /* Let the system pick a port. */
1425 0 : switch (myctladdr.ss_family)
1426 : {
1427 : case AF_INET:
1428 0 : data_addr_sa4->sin_port = 0;
1429 0 : break;
1430 : case AF_INET6:
1431 0 : data_addr_sa6->sin6_port = 0;
1432 0 : break;
1433 : }
1434 :
1435 0 : if (data != -1)
1436 0 : close (data);
1437 0 : data = socket (myctladdr.ss_family, SOCK_STREAM, 0);
1438 0 : if (data < 0)
1439 : {
1440 0 : error (0, errno, "socket");
1441 0 : if (tmpno)
1442 0 : sendport = 1;
1443 0 : return (1);
1444 : }
1445 0 : if (!sendport)
1446 0 : if (setsockopt (data, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on))
1447 : < 0)
1448 : {
1449 0 : error (0, errno, "setsockopt (reuse address)");
1450 0 : goto bad;
1451 : }
1452 0 : if (bind (data, (struct sockaddr *) &data_addr, ctladdrlen) < 0)
1453 : {
1454 0 : error (0, errno, "bind");
1455 0 : goto bad;
1456 : }
1457 0 : if (options & SO_DEBUG
1458 0 : && setsockopt (data, SOL_SOCKET, SO_DEBUG,
1459 : (char *) &on, sizeof (on)) < 0)
1460 0 : if (errno != EACCES) /* Ignore insufficient permission. */
1461 0 : error (0, errno, "setsockopt DEBUG (ignored)");
1462 0 : len = sizeof (data_addr);
1463 0 : if (getsockname (data, (struct sockaddr *) &data_addr, &len) < 0)
1464 : {
1465 0 : error (0, errno, "getsockname");
1466 0 : goto bad;
1467 : }
1468 0 : if (listen (data, 1) < 0)
1469 0 : error (0, errno, "listen");
1470 0 : if (sendport)
1471 : {
1472 : #define UC(b) (((int)b)&0xff)
1473 : /* Preferences:
1474 : * IPv4: EPRT, PORT, LPRT
1475 : * IPv6: EPRT, LPRT
1476 : */
1477 0 : result = ERROR; /* For success detection. */
1478 0 : if (data_addr.ss_family != AF_INET || doepsv4)
1479 : {
1480 : /* Use EPRT mode. */
1481 0 : getnameinfo ((struct sockaddr *) &data_addr, ctladdrlen,
1482 : ia, sizeof (ia), portstr, sizeof (portstr),
1483 : NI_NUMERICHOST | NI_NUMERICSERV);
1484 0 : result = command ("EPRT |%d|%s|%s|",
1485 0 : (data_addr.ss_family == AF_INET) ? 1 : 2,
1486 : ia, portstr);
1487 : }
1488 :
1489 0 : if (data_addr.ss_family == AF_INET && doepsv4 && result != COMPLETE)
1490 : /* Do not try EPRT with IPv4 again. It fails for this host. */
1491 0 : doepsv4 = 0;
1492 :
1493 0 : if (data_addr.ss_family == AF_INET && result != COMPLETE)
1494 : {
1495 : /* PORT for IPv4; possibly EPRT has failed. */
1496 0 : a = (char *) &data_addr_sa4->sin_addr;
1497 0 : p = (char *) &data_addr_sa4->sin_port;
1498 0 : result = command ("PORT %d,%d,%d,%d,%d,%d",
1499 0 : UC (a[0]), UC (a[1]), UC (a[2]), UC (a[3]),
1500 0 : UC (p[0]), UC (p[1]));
1501 : }
1502 :
1503 0 : if (result != COMPLETE)
1504 : {
1505 : /* Fall back to LPRT. */
1506 : uint8_t *h, *p;
1507 :
1508 0 : switch (data_addr.ss_family)
1509 : {
1510 : case AF_INET:
1511 0 : h = (uint8_t *) &data_addr_sa4->sin_addr;
1512 0 : p = (uint8_t *) &data_addr_sa4->sin_port;
1513 0 : result = command ("LPRT 4,4,%u,%u,%u,%u,2,%u,%u",
1514 0 : h[0], h[1], h[2], h[3], p[0], p[1]);
1515 0 : break;
1516 : case AF_INET6:
1517 0 : h = (uint8_t *) &data_addr_sa6->sin6_addr;
1518 0 : p = (uint8_t *) &data_addr_sa6->sin6_port;
1519 0 : result = command ("LPRT 6,16," /* af, hal */
1520 : "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u," /* h[16] */
1521 : "2,%u,%u", /* pal, p[2] */
1522 0 : h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7],
1523 0 : h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15],
1524 0 : p[0], p[1]);
1525 0 : break;
1526 : }
1527 : }
1528 :
1529 0 : if (result == ERROR && sendport == -1)
1530 : {
1531 0 : sendport = 0;
1532 0 : tmpno = 1;
1533 0 : goto noport;
1534 : }
1535 0 : return (result != COMPLETE);
1536 : }
1537 0 : if (tmpno)
1538 0 : sendport = 1;
1539 : #if defined IP_TOS && defined IPPROTO_IP && defined IPTOS_THROUGHPUT
1540 0 : on = IPTOS_THROUGHPUT;
1541 0 : if (data_addr.ss_family == AF_INET &&
1542 0 : setsockopt (data, IPPROTO_IP, IP_TOS, (char *) &on, sizeof (int)) < 0)
1543 0 : error (0, errno, "setsockopt TOS (ignored)");
1544 : #endif
1545 0 : return (0);
1546 : bad:
1547 0 : close (data), data = -1;
1548 0 : if (tmpno)
1549 0 : sendport = 1;
1550 0 : return (1);
1551 : }
1552 :
1553 : FILE *
1554 0 : dataconn (char *lmode)
1555 : {
1556 : struct sockaddr_storage from;
1557 : int s, tos;
1558 0 : socklen_t fromlen = sizeof (from);
1559 :
1560 0 : if (passivemode)
1561 0 : return (fdopen (data, lmode));
1562 :
1563 0 : s = accept (data, (struct sockaddr *) &from, &fromlen);
1564 0 : if (s < 0)
1565 : {
1566 0 : error (0, errno, "accept");
1567 0 : close (data), data = -1;
1568 0 : return (NULL);
1569 : }
1570 0 : close (data);
1571 0 : data = s;
1572 : #if defined IP_TOS && defined IPPROTO_IP && defined IPTOS_THROUGHPUT
1573 0 : tos = IPTOS_THROUGHPUT;
1574 0 : if (from.ss_family == AF_INET &&
1575 0 : setsockopt (s, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof (int)) < 0)
1576 0 : error (0, errno, "setsockopt TOS (ignored)");
1577 : #endif
1578 0 : return (fdopen (data, lmode));
1579 : }
1580 :
1581 : void
1582 0 : ptransfer (char *direction, long long int bytes,
1583 : struct timeval *t0, struct timeval *t1)
1584 : {
1585 : struct timeval td;
1586 : float s, bs;
1587 :
1588 0 : if (verbose)
1589 : {
1590 0 : tvsub (&td, t1, t0);
1591 0 : s = td.tv_sec + (td.tv_usec / 1000000.);
1592 : #define nz(x) ((x) == 0 ? 1 : (x))
1593 0 : bs = bytes / nz (s);
1594 :
1595 0 : printf ("%lld bytes %s in %.3g seconds", bytes, direction, s);
1596 :
1597 0 : if (bs > 1048576.0)
1598 0 : printf (" (%.3g Mbytes/s)\n", bs / 1048576.0);
1599 0 : else if (bs > 1024.0)
1600 0 : printf (" (%.3g kbytes/s)\n", bs / 1024.0);
1601 : else
1602 0 : printf (" (%.3g bytes/s)\n", bs);
1603 : }
1604 0 : }
1605 :
1606 : /*
1607 : void
1608 : tvadd(tsum, t0)
1609 : struct timeval *tsum, *t0;
1610 : {
1611 :
1612 : tsum->tv_sec += t0->tv_sec;
1613 : tsum->tv_usec += t0->tv_usec;
1614 : if (tsum->tv_usec > 1000000)
1615 : tsum->tv_sec++, tsum->tv_usec -= 1000000;
1616 : }
1617 : */
1618 :
1619 : void
1620 0 : tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0)
1621 : {
1622 :
1623 0 : tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
1624 0 : tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
1625 0 : if (tdiff->tv_usec < 0)
1626 0 : tdiff->tv_sec--, tdiff->tv_usec += 1000000;
1627 0 : }
1628 :
1629 : void
1630 0 : psabort (int sig _GL_UNUSED_PARAMETER)
1631 : {
1632 :
1633 0 : abrtflag++;
1634 0 : }
1635 :
1636 : void
1637 6 : pswitch (int flag)
1638 : {
1639 : sighandler_t oldintr;
1640 : static struct comvars
1641 : {
1642 : int connect;
1643 : char *name;
1644 : struct sockaddr_storage mctl;
1645 : struct sockaddr_storage hctl;
1646 : FILE *in;
1647 : FILE *out;
1648 : int tpe;
1649 : int curtpe;
1650 : int cpnd;
1651 : int sunqe;
1652 : int runqe;
1653 : int mcse;
1654 : int ntflg;
1655 : char nti[sizeof (ntin)];
1656 : char nto[sizeof (ntout)];
1657 : int mapflg;
1658 : char *mi;
1659 : char *mo;
1660 : } proxstruct =
1661 : {
1662 : 0}, tmpstruct =
1663 : {
1664 : 0};
1665 : struct comvars *ip, *op;
1666 :
1667 6 : abrtflag = 0;
1668 6 : oldintr = signal (SIGINT, psabort);
1669 6 : if (flag)
1670 : {
1671 6 : if (proxy)
1672 0 : return;
1673 6 : ip = &tmpstruct;
1674 6 : op = &proxstruct;
1675 6 : proxy++;
1676 : }
1677 : else
1678 : {
1679 0 : if (!proxy)
1680 0 : return;
1681 0 : ip = &proxstruct;
1682 0 : op = &tmpstruct;
1683 0 : proxy = 0;
1684 : }
1685 6 : ip->connect = connected;
1686 6 : connected = op->connect;
1687 :
1688 6 : free (ip->name);
1689 6 : ip->name = hostname;
1690 6 : hostname = op->name;
1691 6 : op->name = 0;
1692 :
1693 6 : ip->hctl = hisctladdr;
1694 6 : hisctladdr = op->hctl;
1695 6 : ip->mctl = myctladdr;
1696 6 : myctladdr = op->mctl;
1697 6 : ip->in = cin;
1698 6 : cin = op->in;
1699 6 : ip->out = cout;
1700 6 : cout = op->out;
1701 6 : ip->tpe = type;
1702 6 : type = op->tpe;
1703 6 : ip->curtpe = curtype;
1704 6 : curtype = op->curtpe;
1705 6 : ip->cpnd = cpend;
1706 6 : cpend = op->cpnd;
1707 6 : ip->sunqe = sunique;
1708 6 : sunique = op->sunqe;
1709 6 : ip->runqe = runique;
1710 6 : runique = op->runqe;
1711 6 : ip->mcse = mcase;
1712 6 : mcase = op->mcse;
1713 6 : ip->ntflg = ntflag;
1714 6 : ntflag = op->ntflg;
1715 6 : strncpy (ip->nti, ntin, sizeof (ntin) - 1);
1716 6 : (ip->nti)[strlen (ip->nti)] = '\0';
1717 6 : strcpy (ntin, op->nti);
1718 6 : strncpy (ip->nto, ntout, sizeof (ntout) - 1);
1719 6 : (ip->nto)[strlen (ip->nto)] = '\0';
1720 6 : strcpy (ntout, op->nto);
1721 6 : ip->mapflg = mapflag;
1722 6 : mapflag = op->mapflg;
1723 :
1724 6 : free (ip->mi);
1725 6 : ip->mi = mapin;
1726 6 : mapin = op->mi;
1727 6 : op->mi = 0;
1728 :
1729 6 : free (ip->mo);
1730 6 : ip->mo = mapout;
1731 6 : mapout = op->mo;
1732 6 : op->mo = 0;
1733 :
1734 6 : signal (SIGINT, oldintr);
1735 6 : if (abrtflag)
1736 : {
1737 0 : abrtflag = 0;
1738 0 : (*oldintr) (SIGINT);
1739 : }
1740 : }
1741 :
1742 : void
1743 0 : abortpt (int sig _GL_UNUSED_PARAMETER)
1744 : {
1745 :
1746 0 : printf ("\n");
1747 0 : fflush (stdout);
1748 0 : ptabflg++;
1749 0 : mflag = 0;
1750 0 : abrtflag = 0;
1751 0 : longjmp (ptabort, 1);
1752 : }
1753 :
1754 : void
1755 0 : proxtrans (char *cmd, char *local, char *remote)
1756 : {
1757 : sighandler_t oldintr;
1758 0 : int secndflag = 0, prox_type, nfnd;
1759 : char *cmd2;
1760 : fd_set mask;
1761 :
1762 0 : if (strcmp (cmd, "RETR"))
1763 0 : cmd2 = "RETR";
1764 : else
1765 0 : cmd2 = runique ? "STOU" : "STOR";
1766 0 : if ((prox_type = type) == 0)
1767 : {
1768 0 : if (unix_server && unix_proxy)
1769 0 : prox_type = TYPE_I;
1770 : else
1771 0 : prox_type = TYPE_A;
1772 : }
1773 0 : if (curtype != prox_type)
1774 0 : changetype (prox_type, 1);
1775 0 : if (command ("PASV") != COMPLETE)
1776 : {
1777 0 : printf ("proxy server does not support third party transfers.\n");
1778 0 : return;
1779 : }
1780 0 : pswitch (0);
1781 0 : if (!connected)
1782 : {
1783 0 : printf ("No primary connection\n");
1784 0 : pswitch (1);
1785 0 : code = -1;
1786 0 : return;
1787 : }
1788 0 : if (curtype != prox_type)
1789 0 : changetype (prox_type, 1);
1790 0 : if (command ("PORT %s", pasv) != COMPLETE)
1791 : {
1792 0 : pswitch (1);
1793 0 : return;
1794 : }
1795 0 : if (setjmp (ptabort))
1796 0 : goto abort;
1797 0 : oldintr = signal (SIGINT, abortpt);
1798 0 : if (command ("%s %s", cmd, remote) != PRELIM)
1799 : {
1800 0 : signal (SIGINT, oldintr);
1801 0 : pswitch (1);
1802 0 : return;
1803 : }
1804 0 : sleep (2);
1805 0 : pswitch (1);
1806 0 : secndflag++;
1807 0 : if (command ("%s %s", cmd2, local) != PRELIM)
1808 0 : goto abort;
1809 0 : ptflag++;
1810 0 : getreply (0);
1811 0 : pswitch (0);
1812 0 : getreply (0);
1813 0 : signal (SIGINT, oldintr);
1814 0 : pswitch (1);
1815 0 : ptflag = 0;
1816 0 : printf ("local: %s remote: %s\n", local, remote);
1817 0 : return;
1818 : abort:
1819 0 : signal (SIGINT, SIG_IGN);
1820 0 : ptflag = 0;
1821 0 : if (strcmp (cmd, "RETR") && !proxy)
1822 0 : pswitch (1);
1823 0 : else if (!strcmp (cmd, "RETR") && proxy)
1824 0 : pswitch (0);
1825 0 : if (!cpend && !secndflag)
1826 : { /* only here if cmd = "STOR" (proxy=1) */
1827 0 : if (command ("%s %s", cmd2, local) != PRELIM)
1828 : {
1829 0 : pswitch (0);
1830 0 : if (cpend)
1831 0 : abort_remote ((FILE *) NULL);
1832 : }
1833 0 : pswitch (1);
1834 0 : if (ptabflg)
1835 0 : code = -1;
1836 0 : signal (SIGINT, oldintr);
1837 0 : return;
1838 : }
1839 0 : if (cpend)
1840 0 : abort_remote ((FILE *) NULL);
1841 0 : pswitch (!proxy);
1842 0 : if (!cpend && !secndflag)
1843 : { /* only if cmd = "RETR" (proxy=1) */
1844 0 : if (command ("%s %s", cmd2, local) != PRELIM)
1845 : {
1846 0 : pswitch (0);
1847 0 : if (cpend)
1848 0 : abort_remote ((FILE *) NULL);
1849 0 : pswitch (1);
1850 0 : if (ptabflg)
1851 0 : code = -1;
1852 0 : signal (SIGINT, oldintr);
1853 0 : return;
1854 : }
1855 : }
1856 0 : if (cpend)
1857 0 : abort_remote ((FILE *) NULL);
1858 0 : pswitch (!proxy);
1859 0 : if (cpend)
1860 : {
1861 0 : FD_ZERO (&mask);
1862 0 : FD_SET (fileno (cin), &mask);
1863 0 : if ((nfnd = empty (&mask, 10)) <= 0)
1864 : {
1865 0 : if (nfnd < 0)
1866 : {
1867 0 : error (0, errno, "abort");
1868 : }
1869 0 : if (ptabflg)
1870 0 : code = -1;
1871 0 : lostpeer (0);
1872 : }
1873 0 : getreply (0);
1874 0 : getreply (0);
1875 : }
1876 0 : if (proxy)
1877 0 : pswitch (0);
1878 0 : pswitch (1);
1879 0 : if (ptabflg)
1880 0 : code = -1;
1881 0 : signal (SIGINT, oldintr);
1882 : }
1883 :
1884 : void
1885 0 : reset (int argc _GL_UNUSED_PARAMETER, char **argv _GL_UNUSED_PARAMETER)
1886 : {
1887 : fd_set mask;
1888 0 : int nfnd = 1;
1889 :
1890 0 : FD_ZERO (&mask);
1891 0 : while (nfnd > 0)
1892 : {
1893 0 : FD_SET (fileno (cin), &mask);
1894 0 : if ((nfnd = empty (&mask, 0)) < 0)
1895 : {
1896 0 : error (0, errno, "reset");
1897 0 : code = -1;
1898 0 : lostpeer (0);
1899 : }
1900 0 : else if (nfnd)
1901 : {
1902 0 : getreply (0);
1903 : }
1904 : }
1905 0 : }
1906 :
1907 : char *
1908 0 : gunique (char *local)
1909 : {
1910 : static char *new = 0;
1911 : char *cp;
1912 0 : int count = 0;
1913 0 : char ext = '1';
1914 :
1915 0 : free (new);
1916 0 : new = malloc (strlen (local) + 1 + 3 + 1); /* '.' + 100 + '\0' */
1917 0 : if (!new)
1918 : {
1919 0 : printf ("gunique: malloc failed.\n");
1920 0 : return 0;
1921 : }
1922 0 : strcpy (new, local);
1923 :
1924 0 : cp = new + strlen (new);
1925 0 : *cp++ = '.';
1926 : for (;;)
1927 : {
1928 : struct stat st;
1929 :
1930 0 : if (++count == 100)
1931 : {
1932 0 : printf ("runique: can't find unique file name.\n");
1933 0 : return ((char *) 0);
1934 : }
1935 0 : *cp++ = ext;
1936 0 : *cp = '\0';
1937 0 : if (ext == '9')
1938 0 : ext = '0';
1939 : else
1940 0 : ext++;
1941 :
1942 0 : if (stat (new, &st) != 0)
1943 : {
1944 0 : if (errno == ENOENT)
1945 0 : return new;
1946 : else
1947 0 : return 0;
1948 : }
1949 :
1950 0 : if (ext != '0')
1951 0 : cp--;
1952 0 : else if (*(cp - 2) == '.')
1953 0 : *(cp - 1) = '1';
1954 : else
1955 : {
1956 0 : *(cp - 2) = *(cp - 2) + 1;
1957 0 : cp--;
1958 : }
1959 0 : }
1960 : }
1961 :
1962 : void
1963 0 : abort_remote (FILE *din)
1964 : {
1965 : char buf[BUFSIZ];
1966 : int nfnd;
1967 : fd_set mask;
1968 :
1969 : /*
1970 : * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
1971 : * after urgent byte rather than before as is protocol now
1972 : */
1973 0 : sprintf (buf, "%c%c%c", IAC, IP, IAC);
1974 0 : if (send (fileno (cout), buf, 3, MSG_OOB) != 3)
1975 0 : error (0, errno, "abort");
1976 0 : fprintf (cout, "%cABOR\r\n", DM);
1977 0 : fflush (cout);
1978 0 : FD_ZERO (&mask);
1979 0 : FD_SET (fileno (cin), &mask);
1980 0 : if (din)
1981 : {
1982 0 : FD_SET (fileno (din), &mask);
1983 : }
1984 0 : if ((nfnd = empty (&mask, 10)) <= 0)
1985 : {
1986 0 : if (nfnd < 0)
1987 : {
1988 0 : error (0, errno, "abort");
1989 : }
1990 0 : if (ptabflg)
1991 0 : code = -1;
1992 0 : lostpeer (0);
1993 : }
1994 0 : if (din && FD_ISSET (fileno (din), &mask))
1995 : {
1996 0 : while (read (fileno (din), buf, sizeof (buf)) > 0)
1997 : /* LOOP */ ;
1998 : }
1999 0 : if (getreply (0) == ERROR && code == 552)
2000 : {
2001 : /* 552 needed for nic style abort */
2002 0 : getreply (0);
2003 : }
2004 0 : getreply (0);
2005 0 : }
|