910506827cf62f6079e4535068ca7aa0d9ef7f69
2 * Copyright (c) 1985, 1989 Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 #define L_SET SEEK_SET
23 #define L_INCR SEEK_CUR
24 #define caddr_t void *
27 static char sccsid
[] = "@(#)ftp.c 5.28 (Berkeley) 4/20/89";
30 #ifndef MAXHOSTNAMELEN
31 #define MAXHOSTNAMELEN 64
35 #define vfprintf(a,b,c) _doprnt(b,c,a)
39 /* FD_SET wasn't defined until 4.0. its a cheap test for uid_t presence */
41 #define NBBY 8 /* number of bits in a byte */
43 * Select uses bit masks of file descriptors in longs.
44 * These macros manipulate such bit fields (the filesystem macros use chars).
45 * FD_SETSIZE may be defined by the user, but the default here
46 * should be >= NOFILE (param.h).
49 #define FD_SETSIZE 256
53 #define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
55 #define howmany(x, y) (((x)+((y)-1))/(y))
58 #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
59 #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
60 #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
61 #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
68 struct sockaddr_in hisctladdr
;
69 struct sockaddr_in data_addr
;
74 struct sockaddr_in myctladdr
;
77 off_t restart_point
= 0;
80 int dataconn(const char *mode
);
82 int command(const char *fmt
, ...);
86 typedef void (*Sig_t
)(int);
90 void psabort(int sig
);
92 char *hookup(const char *host
, int port
)
94 register struct hostent
*hp
= 0;
97 static char hostnamebuf
[80];
99 bzero((char *)&hisctladdr
, sizeof (hisctladdr
));
100 hisctladdr
.sin_addr
.s_addr
= inet_addr(host
);
101 if (hisctladdr
.sin_addr
.s_addr
!= (unsigned long)-1) {
102 hisctladdr
.sin_family
= AF_INET
;
103 (void) strncpy(hostnamebuf
, host
, sizeof(hostnamebuf
));
105 hp
= gethostbyname(host
);
107 fprintf(stderr
, "ftp: %s: ", host
);
108 herror((char *)NULL
);
112 hisctladdr
.sin_family
= hp
->h_addrtype
;
113 bcopy(hp
->h_addr_list
[0],
114 (caddr_t
)&hisctladdr
.sin_addr
, hp
->h_length
);
115 (void) strncpy(hostnamebuf
, hp
->h_name
, sizeof(hostnamebuf
));
117 hostname
= hostnamebuf
;
118 s
= socket(hisctladdr
.sin_family
, SOCK_STREAM
, 0);
119 if (s
== INVALID_SOCKET
) {
120 perror("ftp: socket");
124 hisctladdr
.sin_port
= port
;
125 while (connect(s
, (struct sockaddr
*)&hisctladdr
, sizeof (hisctladdr
)) < 0) {
126 if (hp
&& hp
->h_addr_list
[1]) {
129 fprintf(stderr
, "ftp: connect to address %s: ",
130 inet_ntoa(hisctladdr
.sin_addr
));
134 bcopy(hp
->h_addr_list
[0],
135 (caddr_t
)&hisctladdr
.sin_addr
, hp
->h_length
);
136 fprintf(stdout
, "Trying %s...\n",
137 inet_ntoa(hisctladdr
.sin_addr
));
138 (void) fflush(stdout
);
140 s
= socket(hisctladdr
.sin_family
, SOCK_STREAM
, 0);
141 if (s
== INVALID_SOCKET
) {
142 perror("ftp: socket");
148 perror("ftp: connect");
152 len
= sizeof (myctladdr
);
153 if (getsockname(s
, (struct sockaddr
*)&myctladdr
, &len
) < 0) {
154 perror("ftp: getsockname");
160 printf("Connected to %s.\n", hostname
);
161 (void) fflush(stdout
);
163 if (getreply(0) > 2) { /* read startup message from server */
172 if (setsockopt(s
, SOL_SOCKET
, SO_OOBINLINE
, (const char *) &on
, sizeof(on
))
174 perror("ftp: setsockopt");
177 #endif //SO_OOBINLINE
185 int login(const char *host
)
188 char *puser
, *ppass
, *pacct
;
189 const char *user
, *pass
, *acct
;
192 user
= pass
= acct
= 0;
193 n
= ruserpass(host
, &puser
, &ppass
, &pacct
);
203 while (user
== NULL
) {
204 const char *myname
= "none"; // This needs to become the username env
207 printf("Name (%s:%s): ", host
, myname
);
209 printf("Name (%s): ", host
);
210 (void) fflush(stdout
);
211 (void) fgets(tmp
, sizeof(tmp
) - 1, stdin
);
212 tmp
[strlen(tmp
) - 1] = '\0';
218 n
= command("USER %s", user
);
221 pass
= getpass("Password:");
222 n
= command("PASS %s", pass
);
227 acct
= getpass("Account:");
228 n
= command("ACCT %s", acct
);
231 fprintf(stderr
, "Login failed.\n");
234 if (!aflag
&& acct
!= NULL
)
235 (void) command("ACCT %s", acct
);
238 for (n
= 0; n
< macnum
; ++n
) {
239 if (!strcmp("init", macros
[n
].mac_name
)) {
240 (void) strcpy(line
, "$init");
242 domacro(margc
, margv
);
252 extern jmp_buf ptabort
;
255 (void) fflush(stdout
);
262 int command(const char *fmt
, ...)
266 void (*oldintr
)(int);
272 vfprintf(stdout
, fmt
, ap
);
275 (void) fflush(stdout
);
278 perror ("No control connection for command");
282 oldintr
= signal(SIGINT
,cmdabort
);
287 vsprintf(buffer
, fmt
, ap
);
289 //DLJ: to work through firewalls - send the command as a single message
290 strcat(buffer
,"\r\n");
291 fprintfSocket(cout
, buffer
);
293 //DLJ: the following two lines are replaced by the strcat above - seems to
294 // make it work through firewalls.
295 // fprintfSocket(cout, "\r\n");
296 // (void) fflush(cout);
298 r
= getreply(!strcmp(fmt
, "QUIT"));
299 if (abrtflag
&& oldintr
!= SIG_IGN
)
301 // (void) signal(SIGINT, oldintr);
305 char reply_string
[BUFSIZ
]; /* last line of previous reply */
316 int originalcode
= 0, continuation
= 0;
317 void (*oldintr
)(int);
321 oldintr
= signal(SIGINT
,cmdabort
);
325 while ((c
= fgetcSocket(cin
)) != '\n') {
326 if (c
== IAC
) { /* handle telnet commands */
327 switch (fgetcSocket(cin
)) {
330 c
= fgetcSocket(cin
);
331 fprintfSocket(cout
, "%c%c%c",IAC
,DONT
,c
);
335 c
= fgetcSocket(cin
);
336 fprintfSocket(cout
, "%c%c%c",IAC
,WONT
,c
);
346 // (void) signal(SIGINT,oldintr);
352 printf("421 Service not available, remote server has closed connection\n");
353 (void) fflush(stdout
);
358 if (c
!= '\r' && (verbose
> 0 ||
359 (verbose
> -1 && n
== '5' && dig
> 4))) {
361 ((dig
== 1 || dig
== 5) && verbose
== 0))
362 printf("%s:",hostname
);
364 (void) fflush(stdout
);
366 if (dig
< 4 && isdigit(c
))
367 code
= code
* 10 + (c
- '0');
368 if (!pflag
&& code
== 227)
370 if (dig
> 4 && pflag
== 1 && isdigit(c
))
373 if (c
!= '\r' && c
!= ')')
380 if (dig
== 4 && c
== '-') {
387 if (cp
< &reply_string
[sizeof(reply_string
) - 1])
390 if (verbose
> 0 || (verbose
> -1 && n
== '5')) {
392 (void) fflush (stdout
);
394 if (continuation
&& code
!= originalcode
) {
395 if (originalcode
== 0)
402 (void) signal(SIGINT
,oldintr
);
403 if (code
== 421 || originalcode
== 421)
405 if (abrtflag
&& oldintr
!= cmdabort
&& oldintr
!= SIG_IGN
)
418 t
.tv_sec
= (long) sec
;
420 return(select(32, mask
, (struct fd_set
*) 0, (struct fd_set
*) 0, &t
));
431 printf("\nsend aborted\n");
432 (void) fflush(stdout
);
433 longjmp(sendabort
, 1);
437 #define HASHBYTES 1024
439 void sendrequest(const char *cmd
, const char *local
, const char *remote
, int printnames
)
444 sig_t (*oldintr
)(), (*oldintp
)();
445 char buf
[BUFSIZ
], *bufp
;
446 long bytes
= 0, hashbytes
= HASHBYTES
;
449 struct timeval start
, stop
;
452 if (verbose
&& printnames
) {
453 if (local
&& *local
!= '-')
454 printf("local: %s ", local
);
456 printf("remote: %s\n", remote
);
457 (void) fflush(stdout
);
460 proxtrans(cmd
, local
, remote
);
467 if (setjmp(sendabort
)) {
476 null();// (void) signal(SIGINT,oldintr);
478 null();// (void) signal(SIGPIPE,oldintp);
482 null();// oldintr = signal(SIGINT, abortsend);
483 if (strcmp(local
, "-") == 0)
485 else if (*local
== '|') {
486 null();// oldintp = signal(SIGPIPE,SIG_IGN);
487 fin
= _popen(local
+ 1, "r");
490 null();// (void) signal(SIGINT, oldintr);
491 null();// (void) signal(SIGPIPE, oldintp);
497 fin
= fopen(local
, "r");
500 null();// (void) signal(SIGINT, oldintr);
505 if (fstat(fileno(fin
), &st
) < 0 ||
506 (st
.st_mode
&S_IFMT
) != S_IFREG
) {
507 fprintf(stdout
, "%s: not a plain file.\n", local
);
508 (void) fflush(stdout
);
509 null();// (void) signal(SIGINT, oldintr);
516 null();// (void) signal(SIGINT, oldintr);
518 null();// (void) signal(SIGPIPE, oldintp);
520 if (closefunc
!= NULL
)
524 if (setjmp(sendabort
))
528 (strcmp(cmd
, "STOR") == 0 || strcmp(cmd
, "APPE") == 0)) {
529 if (fseek(fin
, (long) restart_point
, 0) < 0) {
532 if (closefunc
!= NULL
)
536 if (command("REST %ld", (long) restart_point
)
539 if (closefunc
!= NULL
)
547 if (command("%s %s", cmd
, remote
) != PRELIM
) {
548 null();// (void) signal(SIGINT, oldintr);
550 null();// (void) signal(SIGPIPE, oldintp);
551 if (closefunc
!= NULL
)
556 if (command("%s", cmd
) != PRELIM
) {
557 null();// (void) signal(SIGINT, oldintr);
559 null();// (void) signal(SIGPIPE, oldintp);
560 if (closefunc
!= NULL
)
564 dout
= dataconn(mode
);
567 (void) gettimeofday(&start
, (struct timezone
*)0);
568 null();// oldintp = signal(SIGPIPE, SIG_IGN);
574 while ((c
= read(fileno(fin
), buf
, sizeof (buf
))) > 0) {
576 for (bufp
= buf
; c
> 0; c
-= d
, bufp
+= d
)
577 if ((d
= send(dout
, bufp
, c
, 0)) <= 0)
580 while (bytes
>= hashbytes
) {
582 hashbytes
+= HASHBYTES
;
584 (void) fflush(stdout
);
587 if (hash
&& bytes
> 0) {
588 if (bytes
< HASHBYTES
)
590 (void) putchar('\n');
591 (void) fflush(stdout
);
597 fprintf(stderr
, "netout: write returned 0?\n");
598 else if (errno
!= EPIPE
)
607 static int bufsize
= 1024;
610 while ((c
= getc(fin
)) != EOF
) {
612 while (hash
&& (bytes
>= hashbytes
)) {
614 (void) fflush(stdout
);
615 hashbytes
+= HASHBYTES
;
617 // Szurgot: The following code is unnecessary on Win32.
618 // (void) fputcSocket(dout, '\r');
622 if (ipos
>= bufsize
) {
623 fputSocket(dout
,buf
,ipos
);
624 if(!hash
) (void) putchar('.');
631 fputSocket(dout
,buf
,ipos
);
635 if (bytes
< hashbytes
)
637 (void) putchar('\n');
638 (void) fflush(stdout
);
642 (void) putchar('\n');
643 (void) fflush(stdout
);
647 // if (ferror(dout)) {
648 // if (errno != EPIPE)
655 (void) gettimeofday(&stop
, (struct timezone
*)0);
656 if (closefunc
!= NULL
)
658 if(closesocket(dout
)) {
659 int iret
=WSAGetLastError ();
660 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
661 (void) fflush(stdout
);
664 null();// (void) signal(SIGINT, oldintr);
666 null();// (void) signal(SIGPIPE, oldintp);
668 ptransfer("sent", bytes
, &start
, &stop
);
671 (void) gettimeofday(&stop
, (struct timezone
*)0);
672 null();// (void) signal(SIGINT, oldintr);
674 null();// (void) signal(SIGPIPE, oldintp);
685 if(closesocket(dout
)) {
686 int iret
=WSAGetLastError ();
687 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
688 (void) fflush(stdout
);
693 if (closefunc
!= NULL
&& fin
!= NULL
)
696 ptransfer("sent", bytes
, &start
, &stop
);
708 (void) fflush(stdout
);
709 longjmp(recvabort
, 1);
713 void recvrequest(const char *cmd
, const char *local
, const char *remote
, const char *mode
,
719 void (*oldintr
)(int), (*oldintp
)(int);
720 int oldverbose
= 0, oldtype
= 0, is_retr
, tcrflag
, nfnd
, bare_lfs
= 0;
722 // static char *buf; // Szurgot: Shouldn't this go SOMEWHERE?
724 static int bufsize
= 1024;
725 long bytes
= 0, hashbytes
= HASHBYTES
;
729 struct timeval start
, stop
;
732 is_retr
= strcmp(cmd
, "RETR") == 0;
733 if (is_retr
&& verbose
&& printnames
) {
734 if (local
&& *local
!= '-')
735 printf("local: %s ", local
);
737 printf("remote: %s\n", remote
);
738 (void) fflush(stdout
);
740 if (proxy
&& is_retr
) {
741 proxtrans(cmd
, local
, remote
);
747 tcrflag
= !crflag
&& is_retr
;
748 if (setjmp(recvabort
)) {
757 null();// (void) signal(SIGINT, oldintr);
761 null();// oldintr = signal(SIGINT, abortrecv);
762 if (strcmp(local
, "-") && *local
!= '|') {
765 // This whole thing is a problem... access Won't work on non-existent files
766 if (access(local
, 2) < 0) {
767 char *dir
= rindex(local
, '/');
769 if (errno
!= ENOENT
&& errno
!= EACCES
) {
771 (void) signal(SIGINT
, oldintr
);
777 d
= access(dir
? local
: ".", 2);
782 (void) signal(SIGINT
, oldintr
);
786 if (!runique
&& errno
== EACCES
&&
787 chmod(local
, 0600) < 0) {
789 (void) signal(SIGINT
, oldintr
);
793 if (runique
&& errno
== EACCES
&&
794 (local
= gunique(local
)) == NULL
) {
795 (void) signal(SIGINT
, oldintr
);
800 else if (runique
&& (local
= gunique(local
)) == NULL
) {
801 (void) signal(SIGINT
, oldintr
);
808 null();// (void) signal(SIGINT, oldintr);
812 if (setjmp(recvabort
))
815 if (type
!= TYPE_A
&& (allbinary
== 0 || type
!= TYPE_I
)) {
817 oldverbose
= verbose
;
821 verbose
= oldverbose
;
823 } else if (restart_point
) {
824 if (command("REST %ld", (long) restart_point
) != CONTINUE
)
828 if (command("%s %s", cmd
, remote
) != PRELIM
) {
829 null();// (void) signal(SIGINT, oldintr);
844 verbose
= oldverbose
;
849 if (command("%s", cmd
) != PRELIM
) {
850 null();// (void) signal(SIGINT, oldintr);
865 verbose
= oldverbose
;
873 if (strcmp(local
, "-") == 0)
875 else if (*local
== '|') {
876 null();// oldintp = signal(SIGPIPE, SIG_IGN);
877 fout
= _popen(local
+ 1, "w");
884 fout
= fopen(local
, mode
);
891 (void) gettimeofday(&start
, (struct timezone
*)0);
897 lseek(fileno(fout
), (long) restart_point
, L_SET
) < 0) {
899 if (closefunc
!= NULL
)
904 // while ((c = recv(din, buf, bufsize, 1)) > 0) {
905 // if ((d = write(fileno(fout), buf, c)) != c)
906 // if ((d = write(fileno(fout), buf, c)) != c)
908 while ((c
= recv(din
, buf
, bufsize
, 0)) > 0) {
909 write(fileno(fout
), buf
, c
);
912 while (bytes
>= hashbytes
) {
914 hashbytes
+= HASHBYTES
;
916 (void) fflush(stdout
);
919 if (hash
&& bytes
> 0) {
920 if (bytes
< HASHBYTES
)
922 (void) putchar('\n');
923 (void) fflush(stdout
);
926 // if (errno != EPIPE)
934 // fprintf(stderr, "%s: short write\n", local);
940 register int i
, n
, c
;
942 if (fseek(fout
, 0L, L_SET
) < 0)
947 if ((c
=getc(fout
)) == EOF
)
952 if (fseek(fout
, 0L, L_INCR
) < 0) {
955 if (closefunc
!= NULL
)
960 while ((c
= fgetcSocket(din
)) != EOF
) {
964 while (hash
&& (bytes
>= hashbytes
)) {
966 (void) fflush(stdout
);
967 hashbytes
+= HASHBYTES
;
970 if ((c
= fgetcSocket(din
)) != '\n' || tcrflag
) {
973 (void) putc('\r', fout
);
982 (void) putc(c
, fout
);
988 printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs
);
989 printf("File may not have transferred correctly.\n");
990 (void) fflush(stdout
);
993 if (bytes
< hashbytes
)
995 (void) putchar('\n');
996 (void) fflush(stdout
);
998 // if (ferror(din)) {
999 // if (errno != EPIPE)
1007 if (closefunc
!= NULL
)
1009 null();// (void) signal(SIGINT, oldintr);
1011 null();// (void) signal(SIGPIPE, oldintp);
1012 (void) gettimeofday(&stop
, (struct timezone
*)0);
1013 if(closesocket(din
)) {
1014 int iret
=WSAGetLastError ();
1015 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
1016 (void) fflush(stdout
);
1020 if (bytes
> 0 && is_retr
)
1021 ptransfer("received", bytes
, &start
, &stop
);
1036 verbose
= oldverbose
;
1041 /* abort using RFC959 recommended IP,SYNC sequence */
1043 (void) gettimeofday(&stop
, (struct timezone
*)0);
1045 null();// (void) signal(SIGPIPE, oldintr);
1046 null();// (void) signal(SIGINT,SIG_IGN);
1061 verbose
= oldverbose
;
1065 null();// (void) signal(SIGINT,oldintr);
1069 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1071 /* send IAC in urgent mode instead of DM because UNIX places oob mark */
1072 /* after urgent byte rather than before as now is protocol */
1073 if (send(cout
,&msg
,1,MSG_OOB
) != 1) {
1076 fprintfSocket(cout
,"%cABOR\r\n",DM
);
1078 FD_SET(cin
, &mask
); // Need to correct this
1080 FD_SET(din
, &mask
); // Need to correct this
1082 if ((nfnd
= empty(&mask
,10)) <= 0) {
1089 if (din
&& FD_ISSET(din
, &mask
)) {
1090 while (recv(din
, buf
, bufsize
, 0) > 0)
1093 if (getreply(0) == ERROR
&& code
== 552) { /* needed for nic style abort */
1106 if (closefunc
!= NULL
&& fout
!= NULL
)
1109 if(closesocket(din
)) {
1110 int iret
=WSAGetLastError ();
1111 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
1112 (void) fflush(stdout
);
1116 ptransfer("received", bytes
, &start
, &stop
);
1117 null();// (void) signal(SIGINT,oldintr);
1123 register char *p
, *a
;
1124 int result
, len
, tmpno
= 0;
1126 int a0
, a1
, a2
, a3
, p0
, p1
;
1130 data
= socket(AF_INET
, SOCK_STREAM
, 0);
1132 perror("ftp: socket");
1135 if ((options
& SO_DEBUG
) &&
1136 setsockopt(data
, SOL_SOCKET
, SO_DEBUG
, (char *)&on
,
1138 perror("ftp: setsockopt (ignored)");
1139 if (command("PASV") != COMPLETE
) {
1140 printf("Passive mode refused.\n");
1145 * What we've got at this point is a string of comma
1146 * separated one-byte unsigned integer values.
1147 * The first four are the an IP address. The fifth is
1148 * the MSB of the port number, the sixth is the LSB.
1149 * From that we'll prepare a sockaddr_in.
1152 if (sscanf(pasv
,"%d,%d,%d,%d,%d,%d",
1153 &a0
, &a1
, &a2
, &a3
, &p0
, &p1
) != 6) {
1154 printf("Passive mode address scan failure. Shouldn't happen!\n");
1158 bzero(&data_addr
, sizeof(data_addr
));
1159 data_addr
.sin_family
= AF_INET
;
1160 a
= (char *)&data_addr
.sin_addr
.s_addr
;
1165 p
= (char *)&data_addr
.sin_port
;
1169 if (connect(data
, (struct sockaddr
*)&data_addr
,
1170 sizeof(data_addr
)) < 0) {
1171 perror("ftp: connect");
1179 data_addr
= myctladdr
;
1181 data_addr
.sin_port
= 0; /* let system pick one */
1183 (void) close (data
);
1184 data
= socket(AF_INET
, SOCK_STREAM
, 0);
1186 perror("ftp: socket");
1192 if (setsockopt(data
, SOL_SOCKET
, SO_REUSEADDR
, (char *)&on
, sizeof (on
)) < 0) {
1193 perror("ftp: setsockopt (reuse address)");
1196 if (bind(data
, (struct sockaddr
*)&data_addr
, sizeof (data_addr
)) < 0) {
1197 perror("ftp: bind");
1200 if (options
& SO_DEBUG
&&
1201 setsockopt(data
, SOL_SOCKET
, SO_DEBUG
, (char *)&on
, sizeof (on
)) < 0)
1202 perror("ftp: setsockopt (ignored)");
1203 len
= sizeof (data_addr
);
1204 if (getsockname(data
, (struct sockaddr
*)&data_addr
, &len
) < 0) {
1205 perror("ftp: getsockname");
1208 if (listen(data
, 1) < 0)
1209 perror("ftp: listen");
1211 a
= (char *)&data_addr
.sin_addr
;
1212 p
= (char *)&data_addr
.sin_port
;
1213 #define UC(b) (((int)b)&0xff)
1215 command("PORT %d,%d,%d,%d,%d,%d",
1216 UC(a
[0]), UC(a
[1]), UC(a
[2]), UC(a
[3]),
1217 UC(p
[0]), UC(p
[1]));
1218 if (result
== ERROR
&& sendport
== -1) {
1223 return (result
!= COMPLETE
);
1229 (void) fflush(stdout
);
1230 (void) close(data
), data
= -1;
1236 int dataconn(const char *mode
)
1238 struct sockaddr_in from
;
1239 int s
, fromlen
= sizeof (from
);
1244 s
= accept(data
, (struct sockaddr
*) &from
, &fromlen
);
1246 perror("ftp: accept");
1247 (void) closesocket(data
), data
= -1;
1250 if(closesocket(data
)) {
1251 int iret
=WSAGetLastError ();
1252 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
1253 (void) fflush(stdout
);
1260 void ptransfer(direction
, bytes
, t0
, t1
)
1261 const char *direction
;
1263 struct timeval
*t0
, *t1
;
1270 s
= td
.tv_sec
+ (td
.tv_usec
/ 1000000.);
1271 #define nz(x) ((x) == 0 ? 1 : (x))
1273 printf("%ld bytes %s in %.1f seconds (%.0f Kbytes/s)\n",
1274 bytes
, direction
, s
, bs
/ 1024.);
1275 (void) fflush(stdout
);
1280 struct timeval *tsum, *t0;
1283 tsum->tv_sec += t0->tv_sec;
1284 tsum->tv_usec += t0->tv_usec;
1285 if (tsum->tv_usec > 1000000)
1286 tsum->tv_sec++, tsum->tv_usec -= 1000000;
1289 void tvsub(tdiff
, t1
, t0
)
1290 struct timeval
*tdiff
, *t1
, *t0
;
1293 tdiff
->tv_sec
= t1
->tv_sec
- t0
->tv_sec
;
1294 tdiff
->tv_usec
= t1
->tv_usec
- t0
->tv_usec
;
1295 if (tdiff
->tv_usec
< 0)
1296 tdiff
->tv_sec
--, tdiff
->tv_usec
+= 1000000;
1299 void psabort(int flag
)
1301 extern int abrtflag
;
1306 void pswitch(int flag
)
1308 extern int proxy
, abrtflag
;
1310 static struct comvars
{
1312 char name
[MAXHOSTNAMELEN
];
1313 struct sockaddr_in mctl
;
1314 struct sockaddr_in hctl
;
1326 char mi
[MAXPATHLEN
];
1327 char mo
[MAXPATHLEN
];
1328 } proxstruct
, tmpstruct
;
1329 struct comvars
*ip
, *op
;
1332 oldintr
= signal(SIGINT
, psabort
);
1347 ip
->connect
= connected
;
1348 connected
= op
->connect
;
1350 (void) strncpy(ip
->name
, hostname
, sizeof(ip
->name
) - 1);
1351 ip
->name
[strlen(ip
->name
)] = '\0';
1354 hostname
= op
->name
;
1355 ip
->hctl
= hisctladdr
;
1356 hisctladdr
= op
->hctl
;
1357 ip
->mctl
= myctladdr
;
1358 myctladdr
= op
->mctl
;
1369 ip
->sunqe
= sunique
;
1370 sunique
= op
->sunqe
;
1371 ip
->runqe
= runique
;
1372 runique
= op
->runqe
;
1377 (void) strncpy(ip
->nti
, ntin
, 16);
1378 (ip
->nti
)[strlen(ip
->nti
)] = '\0';
1379 (void) strcpy(ntin
, op
->nti
);
1380 (void) strncpy(ip
->nto
, ntout
, 16);
1381 (ip
->nto
)[strlen(ip
->nto
)] = '\0';
1382 (void) strcpy(ntout
, op
->nto
);
1383 ip
->mapflg
= mapflag
;
1384 mapflag
= op
->mapflg
;
1385 (void) strncpy(ip
->mi
, mapin
, MAXPATHLEN
- 1);
1386 (ip
->mi
)[strlen(ip
->mi
)] = '\0';
1387 (void) strcpy(mapin
, op
->mi
);
1388 (void) strncpy(ip
->mo
, mapout
, MAXPATHLEN
- 1);
1389 (ip
->mo
)[strlen(ip
->mo
)] = '\0';
1390 (void) strcpy(mapout
, op
->mo
);
1391 // (void) signal(SIGINT, oldintr);
1406 (void) fflush(stdout
);
1410 longjmp(ptabort
, 1);
1414 void proxtrans(cmd
, local
, remote
)
1415 const char *cmd
, *local
, *remote
;
1417 // void (*oldintr)(int);
1418 int tmptype
, oldtype
= 0, secndflag
= 0, nfnd
;
1419 extern jmp_buf ptabort
;
1424 if (strcmp(cmd
, "RETR"))
1427 cmd2
= runique
? "STOU" : "STOR";
1428 if (command("PASV") != COMPLETE
) {
1429 printf("proxy server does not support third part transfers.\n");
1430 (void) fflush(stdout
);
1436 printf("No primary connection\n");
1437 (void) fflush(stdout
);
1442 if (type
!= tmptype
) {
1459 if (command("PORT %s", pasv
) != COMPLETE
) {
1479 if (setjmp(ptabort
))
1481 null();// oldintr = signal(SIGINT, abortpt);
1482 if (command("%s %s", cmd
, remote
) != PRELIM
) {
1483 null();// (void) signal(SIGINT, oldintr);
1506 if (command("%s %s", cmd2
, local
) != PRELIM
)
1512 null();// (void) signal(SIGINT, oldintr);
1531 printf("local: %s remote: %s\n", local
, remote
);
1532 (void) fflush(stdout
);
1535 null();// (void) signal(SIGINT, SIG_IGN);
1537 if (strcmp(cmd
, "RETR") && !proxy
)
1539 else if (!strcmp(cmd
, "RETR") && proxy
)
1541 if (!cpend
&& !secndflag
) { /* only here if cmd = "STOR" (proxy=1) */
1542 if (command("%s %s", cmd2
, local
) != PRELIM
) {
1563 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1565 *(msg
+1) = (char) DM
;
1566 if (send(cout
,msg
,2,MSG_OOB
) != 2)
1568 fprintfSocket(cout
,"ABOR\r\n");
1570 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this
1571 if ((nfnd
= empty(&mask
,10)) <= 0) {
1586 null();// (void) signal(SIGINT, oldintr);
1592 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1594 *(msg
+1) = (char)DM
;
1595 if (send(cout
,msg
,2,MSG_OOB
) != 2)
1597 fprintfSocket(cout
,"ABOR\r\n");
1599 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this...
1600 if ((nfnd
= empty(&mask
,10)) <= 0) {
1612 if (!cpend
&& !secndflag
) { /* only if cmd = "RETR" (proxy=1) */
1613 if (command("%s %s", cmd2
, local
) != PRELIM
) {
1634 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1636 *(msg
+1) = (char)DM
;
1637 if (send(cout
,msg
,2,MSG_OOB
) != 2)
1639 fprintfSocket(cout
,"ABOR\r\n");
1641 // FD_SET(fileno(cin), &mask); // Chris:
1642 if ((nfnd
= empty(&mask
,10)) <= 0) {
1656 null();// (void) signal(SIGINT, oldintr);
1663 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1665 *(msg
+1) = (char)DM
;
1666 if (send(cout
,msg
,2,MSG_OOB
) != 2)
1668 fprintfSocket(cout
,"ABOR\r\n");
1670 // FD_SET(fileno(cin), &mask); // Chris:
1671 if ((nfnd
= empty(&mask
,10)) <= 0) {
1685 // FD_SET(fileno(cin), &mask); // Chris:
1686 if ((nfnd
= empty(&mask
,10)) <= 0) {
1718 null();// (void) signal(SIGINT, oldintr);
1721 void reset(int argc
, const char *argv
[])
1729 // FD_SET(fileno(cin), &mask); // Chris
1730 if ((nfnd
= empty(&mask
,0)) < 0) {
1746 static char new[MAXPATHLEN
];
1747 char *cp
= rindex(local
, '/');
1753 d
= access(cp
? local
: ".", 2);
1760 (void) strcpy(new, local
);
1761 cp
= new + strlen(new);
1764 if (++count
== 100) {
1765 printf("runique: can't find unique file name.\n");
1766 (void) fflush(stdout
);
1775 if ((d
= access(new, 0)) < 0)
1779 else if (*(cp
- 2) == '.')
1782 *(cp
- 2) = *(cp
- 2) + 1;