2 * Copyright (c) 1985, 1989, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 struct sockaddr_storage hisctladdr_ss
;
38 struct sockaddr
*hisctladdr
= (struct sockaddr
*)&hisctladdr_ss
;
39 struct sockaddr_storage data_addr_ss
;
40 struct sockaddr
*data_addr
= (struct sockaddr
*)&data_addr_ss
;
41 struct sockaddr_storage myctladdr_ss
;
42 struct sockaddr
*myctladdr
= (struct sockaddr
*)&myctladdr_ss
;
48 off_t restart_point
= 0;
53 typedef void (*sighand
) (int);
56 hookup (const char *host
, int port
)
58 static char hostnamebuf
[MaxHostNameLen
];
59 struct addrinfo
*ai
, *a
;
60 struct addrinfo hints
;
62 char portstr
[NI_MAXSERV
];
66 memset (&hints
, 0, sizeof(hints
));
67 hints
.ai_socktype
= SOCK_STREAM
;
68 hints
.ai_protocol
= IPPROTO_TCP
;
69 hints
.ai_flags
= AI_CANONNAME
;
71 snprintf (portstr
, sizeof(portstr
), "%u", ntohs(port
));
73 error
= getaddrinfo (host
, portstr
, &hints
, &ai
);
75 warnx ("%s: %s", host
, gai_strerror(error
));
79 strlcpy (hostnamebuf
, host
, sizeof(hostnamebuf
));
80 hostname
= hostnamebuf
;
83 for (a
= ai
; a
!= NULL
; a
= a
->ai_next
) {
84 s
= socket (a
->ai_family
, a
->ai_socktype
, a
->ai_protocol
);
88 if (a
->ai_canonname
!= NULL
)
89 strlcpy (hostnamebuf
, a
->ai_canonname
, sizeof(hostnamebuf
));
91 memcpy (hisctladdr
, a
->ai_addr
, a
->ai_addrlen
);
93 error
= connect (s
, a
->ai_addr
, a
->ai_addrlen
);
97 if (getnameinfo (a
->ai_addr
, a
->ai_addrlen
,
98 addrstr
, sizeof(addrstr
),
99 NULL
, 0, NI_NUMERICHOST
) != 0)
100 strlcpy (addrstr
, "unknown address", sizeof(addrstr
));
102 warn ("connect %s", addrstr
);
111 warnx ("failed to contact %s", host
);
116 len
= sizeof(myctladdr_ss
);
117 if (getsockname (s
, myctladdr
, &len
) < 0) {
118 warn ("getsockname");
123 #ifdef IPTOS_LOWDELAY
124 socket_set_tos (s
, IPTOS_LOWDELAY
);
126 cin
= fdopen (s
, "r");
127 cout
= fdopen (s
, "w");
128 if (cin
== NULL
|| cout
== NULL
) {
129 warnx ("fdopen failed.");
138 printf ("Connected to %s.\n", hostname
);
139 if (getreply (0) > 2) { /* read startup message from server */
147 #if defined(SO_OOBINLINE) && defined(HAVE_SETSOCKOPT)
151 if (setsockopt (s
, SOL_SOCKET
, SO_OOBINLINE
, (char *) &on
, sizeof (on
))
156 #endif /* SO_OOBINLINE */
168 char defaultpass
[128];
169 char *userstr
, *pass
, *acctstr
;
173 struct passwd
*pw
= k_getpwuid(getuid());
176 myname
= pw
->pw_name
;
178 userstr
= pass
= acctstr
= 0;
181 printf("\n*** Using plaintext user and password ***\n\n");
183 printf("Authentication successful.\n\n");
186 if (ruserpass (host
, &userstr
, &pass
, &acctstr
) < 0) {
190 while (userstr
== NULL
) {
192 printf ("Name (%s:%s): ", host
, myname
);
194 printf ("Name (%s): ", host
);
196 if (fgets (tmp
, sizeof (tmp
) - 1, stdin
) != NULL
)
197 tmp
[strlen (tmp
) - 1] = '\0';
203 strlcpy(username
, userstr
, sizeof(username
));
204 n
= command("USER %s", userstr
);
206 n
= command("PASS dummy"); /* DK: Compatibility with gssftp daemon */
207 else if(n
== CONTINUE
) {
211 (!strcmp(userstr
, "ftp") || !strcmp(userstr
, "anonymous"))) {
212 snprintf(defaultpass
, sizeof(defaultpass
),
213 "%s@%s", myname
, mydomain
);
214 snprintf(prompt
, sizeof(prompt
),
215 "Password (%s): ", defaultpass
);
216 } else if (sec_complete
) {
220 snprintf(prompt
, sizeof(prompt
), "Password: ");
224 UI_UTIL_read_pw_string (tmp
, sizeof (tmp
), prompt
, 0);
229 n
= command ("PASS %s", pass
);
234 UI_UTIL_read_pw_string (acctstr
, 128, "Account:", 0);
235 n
= command ("ACCT %s", acctstr
);
238 warnx ("Login failed.");
241 if (!aflag
&& acctstr
!= NULL
)
242 command ("ACCT %s", acctstr
);
245 for (n
= 0; n
< macnum
; ++n
) {
246 if (!strcmp("init", macros
[n
].mac_name
)) {
247 strlcpy (line
, "$init", sizeof (line
));
249 domacro(margc
, margv
);
253 sec_set_protection_level ();
265 longjmp (ptabort
, 1);
269 command (char *fmt
,...)
277 warn ("No control connection for command");
281 oldintr
= signal(SIGINT
, cmdabort
);
284 if (strncmp("PASS ", fmt
, 5) == 0)
288 vfprintf(stdout
, fmt
, ap
);
293 sec_vfprintf(cout
, fmt
, ap
);
299 fprintf (cout
, "\r\n");
302 r
= getreply (!strcmp (fmt
, "QUIT"));
303 if (abrtflag
&& oldintr
!= SIG_IGN
)
305 signal (SIGINT
, oldintr
);
309 char reply_string
[BUFSIZ
]; /* last line of previous reply */
312 getreply (int expecteof
)
317 struct sigaction sa
, osa
;
322 sigemptyset (&sa
.sa_mask
);
324 sa
.sa_handler
= cmdabort
;
325 sigaction (SIGINT
, &sa
, &osa
);
335 sigaction (SIGINT
, &osa
, NULL
);
341 printf ("421 Service not available, "
342 "remote server has closed connection\n");
349 if (c
== WILL
|| c
== WONT
)
350 fprintf (cout
, "%c%c%c", IAC
, DONT
, getc (cin
));
351 if (c
== DO
|| c
== DONT
)
352 fprintf (cout
, "%c%c%c", IAC
, WONT
, getc (cin
));
356 if(isdigit((unsigned char)buf
[0])){
357 sscanf(buf
, "%d", &code
);
360 sec_read_msg(buf
, prot_safe
);
361 sscanf(buf
, "%d", &code
);
363 } else if(code
== 632){
365 sec_read_msg(buf
, prot_private
);
366 sscanf(buf
, "%d", &code
);
368 }else if(code
== 633){
370 sec_read_msg(buf
, prot_confidential
);
371 sscanf(buf
, "%d", &code
);
373 }else if(sec_complete
)
377 if(code
!= 0 && reply_code
== 0)
379 if (verbose
> 0 || (verbose
> -1 && code
> 499))
380 fprintf (stdout
, "%s%s\n", lead_string
, buf
);
381 if (code
== reply_code
&& buf
[3] == ' ') {
382 strlcpy (reply_string
, buf
, sizeof(reply_string
));
385 sigaction (SIGINT
, &osa
, NULL
);
390 osa
.sa_handler
!= cmdabort
&&
391 osa
.sa_handler
!= SIG_IGN
)
392 osa
.sa_handler (SIGINT
);
394 if (code
== 227 || code
== 229) {
397 q
= strchr (reply_string
, '(');
400 strlcpy(pasv
, q
, sizeof(pasv
));
401 q
= strrchr(pasv
, ')');
409 if(verbose
> 0 || (verbose
> -1 && code
> 499)){
411 fprintf(stdout
, "!!");
412 fprintf(stdout
, "%s\n", buf
);
419 if(p
< buf
+ sizeof(buf
) - 1)
421 else if(long_warn
== 0) {
422 fprintf(stderr
, "WARNING: incredibly long line received\n");
433 getreply (int expecteof
)
437 int originalcode
= 0, continuation
= 0;
440 char *cp
, *pt
= pasv
;
442 oldintr
= signal (SIGINT
, cmdabort
);
446 while ((c
= getc (cin
)) != '\n') {
447 if (c
== IAC
) { /* handle telnet commands */
448 switch (c
= getc (cin
)) {
452 fprintf (cout
, "%c%c%c", IAC
, DONT
, c
);
458 fprintf (cout
, "%c%c%c", IAC
, WONT
, c
);
469 signal (SIGINT
, oldintr
);
475 printf ("421 Service not available, remote server has closed connection\n");
481 if (c
!= '\r' && (verbose
> 0 ||
482 (verbose
> -1 && n
== '5' && dig
> 4))) {
484 (dig
== 1 || dig
== 5 && verbose
== 0))
485 printf ("%s:", hostname
);
488 if (dig
< 4 && isdigit (c
))
489 code
= code
* 10 + (c
- '0');
490 if (!pflag
&& code
== 227)
492 if (dig
> 4 && pflag
== 1 && isdigit (c
))
495 if (c
!= '\r' && c
!= ')')
502 if (dig
== 4 && c
== '-') {
509 if (cp
< &reply_string
[sizeof (reply_string
) - 1])
512 if (verbose
> 0 || verbose
> -1 && n
== '5') {
516 if (continuation
&& code
!= originalcode
) {
517 if (originalcode
== 0)
524 sec_read_msg(reply_string
, prot_safe
);
526 sec_read_msg(reply_string
, prot_private
);
528 sec_read_msg(reply_string
, prot_confidential
);
529 n
= code
/ 100 + '0';
533 signal (SIGINT
, oldintr
);
534 if (code
== 421 || originalcode
== 421)
536 if (abrtflag
&& oldintr
!= cmdabort
&& oldintr
!= SIG_IGN
)
545 empty (fd_set
* mask
, int sec
)
551 return (select (FD_SETSIZE
, mask
, NULL
, NULL
, &t
));
562 printf ("\nsend aborted\nwaiting for remote to finish abort\n");
564 longjmp (sendabort
, 1);
567 #define HASHBYTES 1024
570 copy_stream (FILE * from
, FILE * to
)
572 static size_t bufsize
;
577 int hashbytes
= HASHBYTES
;
580 #if defined(HAVE_MMAP) && !defined(NO_MMAP)
584 #define BLOCKSIZE (1024 * 1024 * 10)
587 #define MAP_FAILED (-1)
590 if (fstat (fileno (from
), &st
) == 0 && S_ISREG (st
.st_mode
)) {
592 * mmap zero bytes has potential of loosing, don't do it.
597 while (off
!= st
.st_size
) {
601 len
= st
.st_size
- off
;
605 chunk
= mmap (0, len
, PROT_READ
, MAP_SHARED
, fileno (from
), off
);
606 if (chunk
== (void *) MAP_FAILED
) {
607 if (off
== 0) /* try read if mmap doesn't work */
612 res
= sec_write (fileno (to
), chunk
, len
);
613 if (msync (chunk
, len
, MS_ASYNC
))
615 if (munmap (chunk
, len
) < 0)
627 buf
= alloc_buffer (buf
, &bufsize
,
628 fstat (fileno (from
), &st
) >= 0 ? &st
: NULL
);
632 while ((n
= read (fileno (from
), buf
, bufsize
)) > 0) {
633 werr
= sec_write (fileno (to
), buf
, n
);
637 while (hash
&& bytes
> hashbytes
) {
639 hashbytes
+= HASHBYTES
;
655 sendrequest (char *cmd
, char *local
, char *remote
, char *lmode
, int printnames
)
658 struct timeval start
, stop
;
660 FILE *fin
, *dout
= 0;
661 int (*closefunc
) (FILE *);
662 RETSIGTYPE (*oldintr
)(int), (*oldintp
)(int);
663 long bytes
= 0, hashbytes
= HASHBYTES
;
666 if (verbose
&& printnames
) {
667 if (local
&& strcmp (local
, "-") != 0)
668 printf ("local: %s ", local
);
670 printf ("remote: %s\n", remote
);
673 proxtrans (cmd
, local
, remote
);
677 changetype (type
, 0);
682 if (setjmp (sendabort
)) {
691 signal (SIGINT
, oldintr
);
693 signal (SIGPIPE
, oldintp
);
697 oldintr
= signal (SIGINT
, abortsend
);
698 if (strcmp (local
, "-") == 0)
700 else if (*local
== '|') {
701 oldintp
= signal (SIGPIPE
, SIG_IGN
);
702 fin
= popen (local
+ 1, lmode
);
704 warn ("%s", local
+ 1);
705 signal (SIGINT
, oldintr
);
706 signal (SIGPIPE
, oldintp
);
712 fin
= fopen (local
, lmode
);
714 warn ("local: %s", local
);
715 signal (SIGINT
, oldintr
);
720 if (fstat (fileno (fin
), &st
) < 0 ||
721 (st
.st_mode
& S_IFMT
) != S_IFREG
) {
722 fprintf (stdout
, "%s: not a plain file.\n", local
);
723 signal (SIGINT
, oldintr
);
730 signal (SIGINT
, oldintr
);
732 signal (SIGPIPE
, oldintp
);
734 if (closefunc
!= NULL
)
738 if (setjmp (sendabort
))
742 (strcmp (cmd
, "STOR") == 0 || strcmp (cmd
, "APPE") == 0)) {
747 rc
= fseek (fin
, (long) restart_point
, SEEK_SET
);
751 rc
= lseek (fileno (fin
), restart_point
, SEEK_SET
);
757 warn ("local: %s", local
);
759 if (closefunc
!= NULL
)
763 if (command ("REST %ld", (long) restart_point
)
766 if (closefunc
!= NULL
)
774 if (command ("%s %s", cmd
, remote
) != PRELIM
) {
775 signal (SIGINT
, oldintr
);
777 signal (SIGPIPE
, oldintp
);
778 if (closefunc
!= NULL
)
782 } else if (command ("%s", cmd
) != PRELIM
) {
783 signal(SIGINT
, oldintr
);
785 signal(SIGPIPE
, oldintp
);
786 if (closefunc
!= NULL
)
790 dout
= dataconn(rmode
);
793 set_buffer_size (fileno (dout
), 0);
794 gettimeofday (&start
, (struct timezone
*) 0);
795 oldintp
= signal (SIGPIPE
, SIG_IGN
);
801 bytes
= copy_stream (fin
, dout
);
805 while ((c
= getc (fin
)) != EOF
) {
807 while (hash
&& (bytes
>= hashbytes
)) {
810 hashbytes
+= HASHBYTES
;
814 sec_putc ('\r', dout
);
822 if (bytes
< hashbytes
)
828 warn ("local: %s", local
);
836 if (closefunc
!= NULL
)
839 gettimeofday (&stop
, (struct timezone
*) 0);
841 signal (SIGINT
, oldintr
);
843 signal (SIGPIPE
, oldintp
);
845 ptransfer ("sent", bytes
, &start
, &stop
);
848 signal (SIGINT
, oldintr
);
850 signal (SIGPIPE
, oldintp
);
863 if (closefunc
!= NULL
&& fin
!= NULL
)
865 gettimeofday (&stop
, (struct timezone
*) 0);
867 ptransfer ("sent", bytes
, &start
, &stop
);
878 printf ("\nreceive aborted\nwaiting for remote to finish abort\n");
880 longjmp (recvabort
, 1);
884 recvrequest (char *cmd
, char *local
, char *remote
,
885 char *lmode
, int printnames
, int local_given
)
887 FILE *fout
= NULL
, *din
= NULL
;
888 int (*closefunc
) (FILE *);
889 sighand oldintr
, oldintp
;
890 int c
, d
, is_retr
, tcrflag
, bare_lfs
= 0;
891 static size_t bufsize
;
893 long bytes
= 0, hashbytes
= HASHBYTES
;
894 struct timeval start
, stop
;
897 is_retr
= strcmp (cmd
, "RETR") == 0;
898 if (is_retr
&& verbose
&& printnames
) {
899 if (local
&& strcmp (local
, "-") != 0)
900 printf ("local: %s ", local
);
902 printf ("remote: %s\n", remote
);
904 if (proxy
&& is_retr
) {
905 proxtrans (cmd
, local
, remote
);
911 tcrflag
= !crflag
&& is_retr
;
912 if (setjmp (recvabort
)) {
921 signal (SIGINT
, oldintr
);
925 oldintr
= signal (SIGINT
, abortrecv
);
926 if (!local_given
|| (strcmp (local
, "-") && *local
!= '|')) {
927 if (access (local
, 2) < 0) {
928 char *dir
= strrchr (local
, '/');
930 if (errno
!= ENOENT
&& errno
!= EACCES
) {
931 warn ("local: %s", local
);
932 signal (SIGINT
, oldintr
);
938 d
= access (dir
? local
: ".", 2);
942 warn ("local: %s", local
);
943 signal (SIGINT
, oldintr
);
947 if (!runique
&& errno
== EACCES
&&
948 chmod (local
, 0600) < 0) {
949 warn ("local: %s", local
);
950 signal (SIGINT
, oldintr
);
951 signal (SIGINT
, oldintr
);
955 if (runique
&& errno
== EACCES
&&
956 (local
= gunique (local
)) == NULL
) {
957 signal (SIGINT
, oldintr
);
961 } else if (runique
&& (local
= gunique (local
)) == NULL
) {
962 signal(SIGINT
, oldintr
);
968 if (curtype
!= TYPE_A
)
969 changetype (TYPE_A
, 0);
970 } else if (curtype
!= type
)
971 changetype (type
, 0);
973 signal (SIGINT
, oldintr
);
977 if (setjmp (recvabort
))
979 if (is_retr
&& restart_point
&&
980 command ("REST %ld", (long) restart_point
) != CONTINUE
)
983 if (command ("%s %s", cmd
, remote
) != PRELIM
) {
984 signal (SIGINT
, oldintr
);
988 if (command ("%s", cmd
) != PRELIM
) {
989 signal (SIGINT
, oldintr
);
993 din
= dataconn ("r");
996 set_buffer_size (fileno (din
), 1);
997 if (local_given
&& strcmp (local
, "-") == 0)
999 else if (local_given
&& *local
== '|') {
1000 oldintp
= signal (SIGPIPE
, SIG_IGN
);
1001 fout
= popen (local
+ 1, "w");
1003 warn ("%s", local
+ 1);
1008 fout
= fopen (local
, lmode
);
1010 warn ("local: %s", local
);
1015 buf
= alloc_buffer (buf
, &bufsize
,
1016 fstat (fileno (fout
), &st
) >= 0 ? &st
: NULL
);
1020 gettimeofday (&start
, (struct timezone
*) 0);
1025 if (restart_point
&&
1026 lseek (fileno (fout
), restart_point
, SEEK_SET
) < 0) {
1027 warn ("local: %s", local
);
1028 if (closefunc
!= NULL
)
1029 (*closefunc
) (fout
);
1033 while ((c
= sec_read (fileno (din
), buf
, bufsize
)) > 0) {
1034 if ((d
= write (fileno (fout
), buf
, c
)) != c
)
1038 while (bytes
>= hashbytes
) {
1040 hashbytes
+= HASHBYTES
;
1045 if (hash
&& bytes
> 0) {
1046 if (bytes
< HASHBYTES
)
1058 warn ("local: %s", local
);
1060 warnx ("%s: short write", local
);
1065 if (restart_point
) {
1068 if (fseek (fout
, 0L, SEEK_SET
) < 0)
1071 for (i
= 0; i
++ < n
;) {
1072 if ((ch
= sec_getc (fout
)) == EOF
)
1077 if (fseek (fout
, 0L, SEEK_CUR
) < 0) {
1079 warn ("local: %s", local
);
1080 if (closefunc
!= NULL
)
1081 (*closefunc
) (fout
);
1085 while ((c
= sec_getc(din
)) != EOF
) {
1089 while (hash
&& (bytes
>= hashbytes
)) {
1092 hashbytes
+= HASHBYTES
;
1095 if ((c
= sec_getc (din
)) != '\n' || tcrflag
) {
1113 printf ("WARNING! %d bare linefeeds received in ASCII mode\n",
1115 printf ("File may not have transferred correctly.\n");
1118 if (bytes
< hashbytes
)
1129 warn ("local: %s", local
);
1132 if (closefunc
!= NULL
)
1133 (*closefunc
) (fout
);
1134 signal (SIGINT
, oldintr
);
1136 signal (SIGPIPE
, oldintp
);
1138 gettimeofday (&stop
, (struct timezone
*) 0);
1140 if (bytes
> 0 && is_retr
)
1141 ptransfer ("received", bytes
, &start
, &stop
);
1145 /* abort using RFC959 recommended IP,SYNC sequence */
1148 signal (SIGPIPE
, oldintr
);
1149 signal (SIGINT
, SIG_IGN
);
1152 signal (SIGINT
, oldintr
);
1161 if (closefunc
!= NULL
&& fout
!= NULL
)
1162 (*closefunc
) (fout
);
1165 gettimeofday (&stop
, (struct timezone
*) 0);
1167 ptransfer ("received", bytes
, &start
, &stop
);
1168 signal (SIGINT
, oldintr
);
1172 parse_epsv (const char *str
)
1185 port
= strtol (str
, &end
, 0);
1188 if (end
[0] != sep
|| end
[1] != '\0')
1194 parse_pasv (struct sockaddr_in
*sin4
, const char *str
)
1196 int a0
, a1
, a2
, a3
, p0
, p1
;
1199 * What we've got at this point is a string of comma separated
1200 * one-byte unsigned integer values. The first four are the an IP
1201 * address. The fifth is the MSB of the port number, the sixth is the
1202 * LSB. From that we'll prepare a sockaddr_in.
1205 if (sscanf (str
, "%d,%d,%d,%d,%d,%d",
1206 &a0
, &a1
, &a2
, &a3
, &p0
, &p1
) != 6) {
1207 printf ("Passive mode address scan failure. "
1208 "Shouldn't happen!\n");
1211 if (a0
< 0 || a0
> 255 ||
1212 a1
< 0 || a1
> 255 ||
1213 a2
< 0 || a2
> 255 ||
1214 a3
< 0 || a3
> 255 ||
1215 p0
< 0 || p0
> 255 ||
1216 p1
< 0 || p1
> 255) {
1217 printf ("Can't parse passive mode string.\n");
1220 memset (sin4
, 0, sizeof(*sin4
));
1221 sin4
->sin_family
= AF_INET
;
1222 sin4
->sin_addr
.s_addr
= htonl ((a0
<< 24) | (a1
<< 16) |
1224 sin4
->sin_port
= htons ((p0
<< 8) | p1
);
1233 data
= socket (myctladdr
->sa_family
, SOCK_STREAM
, 0);
1238 if (options
& SO_DEBUG
)
1239 socket_set_debug (data
);
1240 if (command ("EPSV") != COMPLETE
) {
1241 if (command ("PASV") != COMPLETE
) {
1242 printf ("Passive mode refused.\n");
1248 * Parse the reply to EPSV or PASV
1251 port
= parse_epsv (pasv
);
1253 data_addr
->sa_family
= myctladdr
->sa_family
;
1254 socket_set_address_and_port (data_addr
,
1255 socket_get_address (hisctladdr
),
1258 if (parse_pasv ((struct sockaddr_in
*)data_addr
, pasv
) < 0)
1262 if (connect (data
, data_addr
, socket_sockaddr_size (data_addr
)) < 0) {
1266 #ifdef IPTOS_THROUGHPUT
1267 socket_set_tos (data
, IPTOS_THROUGHPUT
);
1286 data_addr
->sa_family
= myctladdr
->sa_family
;
1287 socket_set_address_and_port (data_addr
, socket_get_address (myctladdr
),
1288 sendport
? 0 : socket_get_port (myctladdr
));
1292 data
= socket (data_addr
->sa_family
, SOCK_STREAM
, 0);
1300 socket_set_reuseaddr (data
, 1);
1301 if (bind (data
, data_addr
, socket_sockaddr_size (data_addr
)) < 0) {
1305 if (options
& SO_DEBUG
)
1306 socket_set_debug (data
);
1307 len
= sizeof (data_addr_ss
);
1308 if (getsockname (data
, data_addr
, &len
) < 0) {
1309 warn ("getsockname");
1312 if (listen (data
, 1) < 0)
1319 if (inet_ntop (data_addr
->sa_family
, socket_get_address (data_addr
),
1320 addr_str
, sizeof(addr_str
)) == NULL
)
1321 errx (1, "inet_ntop failed");
1322 switch (data_addr
->sa_family
) {
1332 errx (1, "bad address family %d", data_addr
->sa_family
);
1340 result
= command ("EPRT |%d|%s|%d|",
1342 ntohs(socket_get_port (data_addr
)));
1345 if (result
== ERROR
) {
1346 struct sockaddr_in
*sin4
= (struct sockaddr_in
*)data_addr
;
1348 unsigned int a
= ntohl(sin4
->sin_addr
.s_addr
);
1349 unsigned int p
= ntohs(sin4
->sin_port
);
1351 if (data_addr
->sa_family
!= AF_INET
) {
1352 warnx ("remote server doesn't support EPRT");
1356 result
= command("PORT %d,%d,%d,%d,%d,%d",
1363 if (result
== ERROR
&& sendport
== -1) {
1368 return (result
!= COMPLETE
);
1370 return result
!= COMPLETE
;
1376 #ifdef IPTOS_THROUGHPUT
1377 socket_set_tos (data
, IPTOS_THROUGHPUT
);
1389 * Need to start a listen on the data channel before we send the command,
1390 * otherwise the server's connect may fail.
1396 return passive_mode ();
1398 return active_mode ();
1402 dataconn (const char *lmode
)
1404 struct sockaddr_storage from_ss
;
1405 struct sockaddr
*from
= (struct sockaddr
*)&from_ss
;
1406 socklen_t fromlen
= sizeof(from_ss
);
1410 return (fdopen (data
, lmode
));
1412 s
= accept (data
, from
, &fromlen
);
1415 close (data
), data
= -1;
1420 #ifdef IPTOS_THROUGHPUT
1421 socket_set_tos (s
, IPTOS_THROUGHPUT
);
1423 return (fdopen (data
, lmode
));
1427 ptransfer (char *direction
, long int bytes
,
1428 struct timeval
* t0
, struct timeval
* t1
)
1437 td
.tv_sec
= t1
->tv_sec
- t0
->tv_sec
;
1438 td
.tv_usec
= t1
->tv_usec
- t0
->tv_usec
;
1439 if (td
.tv_usec
< 0) {
1441 td
.tv_usec
+= 1000000;
1443 s
= td
.tv_sec
+ (td
.tv_usec
/ 1000000.);
1444 bs
= bytes
/ (s
? s
: 1);
1445 if (bs
>= 1048576) {
1449 } else if (bs
>= 1024) {
1458 printf ("%ld bytes %s in %.3g seconds (%.*f %sbyte/s)\n",
1459 bytes
, direction
, s
, prec
, bs
, unit
);
1474 static struct comvars
{
1476 char name
[MaxHostNameLen
];
1477 struct sockaddr_storage mctl
;
1478 struct sockaddr_storage hctl
;
1491 char mi
[MaxPathLen
];
1492 char mo
[MaxPathLen
];
1493 } proxstruct
, tmpstruct
;
1494 struct comvars
*ip
, *op
;
1497 oldintr
= signal (SIGINT
, psabort
);
1511 ip
->connect
= connected
;
1512 connected
= op
->connect
;
1514 strlcpy (ip
->name
, hostname
, sizeof (ip
->name
));
1517 hostname
= op
->name
;
1518 ip
->hctl
= hisctladdr_ss
;
1519 hisctladdr_ss
= op
->hctl
;
1520 ip
->mctl
= myctladdr_ss
;
1521 myctladdr_ss
= op
->mctl
;
1528 ip
->curtpe
= curtype
;
1529 curtype
= op
->curtpe
;
1532 ip
->sunqe
= sunique
;
1533 sunique
= op
->sunqe
;
1534 ip
->runqe
= runique
;
1535 runique
= op
->runqe
;
1540 strlcpy (ip
->nti
, ntin
, sizeof (ip
->nti
));
1541 strlcpy (ntin
, op
->nti
, 17);
1542 strlcpy (ip
->nto
, ntout
, sizeof (ip
->nto
));
1543 strlcpy (ntout
, op
->nto
, 17);
1544 ip
->mapflg
= mapflag
;
1545 mapflag
= op
->mapflg
;
1546 strlcpy (ip
->mi
, mapin
, MaxPathLen
);
1547 strlcpy (mapin
, op
->mi
, MaxPathLen
);
1548 strlcpy (ip
->mo
, mapout
, MaxPathLen
);
1549 strlcpy (mapout
, op
->mo
, MaxPathLen
);
1550 signal(SIGINT
, oldintr
);
1553 (*oldintr
) (SIGINT
);
1566 longjmp (ptabort
, 1);
1570 proxtrans (char *cmd
, char *local
, char *remote
)
1572 sighand oldintr
= NULL
;
1573 int secndflag
= 0, prox_type
, nfnd
;
1577 if (strcmp (cmd
, "RETR"))
1580 cmd2
= runique
? "STOU" : "STOR";
1581 if ((prox_type
= type
) == 0) {
1582 if (unix_server
&& unix_proxy
)
1587 if (curtype
!= prox_type
)
1588 changetype (prox_type
, 1);
1589 if (command ("PASV") != COMPLETE
) {
1590 printf ("proxy server does not support third party transfers.\n");
1595 printf ("No primary connection\n");
1600 if (curtype
!= prox_type
)
1601 changetype (prox_type
, 1);
1602 if (command ("PORT %s", pasv
) != COMPLETE
) {
1606 if (setjmp (ptabort
))
1608 oldintr
= signal (SIGINT
, abortpt
);
1609 if (command ("%s %s", cmd
, remote
) != PRELIM
) {
1610 signal (SIGINT
, oldintr
);
1617 if (command ("%s %s", cmd2
, local
) != PRELIM
)
1623 signal (SIGINT
, oldintr
);
1626 printf ("local: %s remote: %s\n", local
, remote
);
1629 signal (SIGINT
, SIG_IGN
);
1631 if (strcmp (cmd
, "RETR") && !proxy
)
1633 else if (!strcmp (cmd
, "RETR") && proxy
)
1635 if (!cpend
&& !secndflag
) { /* only here if cmd = "STOR" (proxy=1) */
1636 if (command ("%s %s", cmd2
, local
) != PRELIM
) {
1639 abort_remote ((FILE *) NULL
);
1645 signal (SIGINT
, oldintr
);
1649 abort_remote ((FILE *) NULL
);
1651 if (!cpend
&& !secndflag
) { /* only if cmd = "RETR" (proxy=1) */
1652 if (command ("%s %s", cmd2
, local
) != PRELIM
) {
1655 abort_remote ((FILE *) NULL
);
1659 signal (SIGINT
, oldintr
);
1664 abort_remote ((FILE *) NULL
);
1668 if (fileno(cin
) >= FD_SETSIZE
)
1669 errx (1, "fd too large");
1670 FD_SET (fileno (cin
), &mask
);
1671 if ((nfnd
= empty (&mask
, 10)) <= 0) {
1687 signal (SIGINT
, oldintr
);
1691 reset (int argc
, char **argv
)
1698 if (fileno (cin
) >= FD_SETSIZE
)
1699 errx (1, "fd too large");
1700 FD_SET (fileno (cin
), &mask
);
1701 if ((nfnd
= empty (&mask
, 0)) < 0) {
1712 gunique (char *local
)
1714 static char new[MaxPathLen
];
1715 char *cp
= strrchr (local
, '/');
1721 d
= access (cp
? local
: ".", 2);
1725 warn ("local: %s", local
);
1728 strlcpy (new, local
, sizeof(new));
1729 cp
= new + strlen(new);
1732 if (++count
== 100) {
1733 printf ("runique: can't find unique file name.\n");
1742 if ((d
= access (new, 0)) < 0)
1746 else if (*(cp
- 2) == '.')
1749 *(cp
- 2) = *(cp
- 2) + 1;
1757 abort_remote (FILE * din
)
1764 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
1765 * after urgent byte rather than before as is protocol now
1767 snprintf (buf
, sizeof (buf
), "%c%c%c", IAC
, IP
, IAC
);
1768 if (send (fileno (cout
), buf
, 3, MSG_OOB
) != 3)
1770 fprintf (cout
, "%c", DM
);
1771 sec_fprintf(cout
, "ABOR");
1773 fprintf (cout
, "\r\n");
1776 if (fileno (cin
) >= FD_SETSIZE
)
1777 errx (1, "fd too large");
1778 FD_SET (fileno (cin
), &mask
);
1780 if (fileno (din
) >= FD_SETSIZE
)
1781 errx (1, "fd too large");
1782 FD_SET (fileno (din
), &mask
);
1784 if ((nfnd
= empty (&mask
, 10)) <= 0) {
1792 if (din
&& FD_ISSET (fileno (din
), &mask
)) {
1793 while (read (fileno (din
), buf
, BUFSIZ
) > 0)
1796 if (getreply (0) == ERROR
&& code
== 552) {
1797 /* 552 needed for nic style abort */