2 #define L_INCR SEEK_CUR
5 * Copyright (c) 1985, 1989 Regents of the University of California.
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the University of California, Berkeley. The name of the
14 * University may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 static char sccsid
[] = "@(#)ftp.c 5.28 (Berkeley) 4/20/89";
29 #include <sys/param.h>
30 #include <sys/socket.h>
33 #include <sys/ioctl.h>
34 #include <netinet/in.h>
36 #include <arpa/telnet.h>
50 #include "prototypes.h"
51 #ifndef MAXHOSTNAMELEN
52 #define MAXHOSTNAMELEN 64
56 #define vfprintf(a,b,c) _doprnt(b,c,a)
60 /* FD_SET wasn't defined until 4.0. its a cheap test for uid_t presence */
62 #define NBBY 8 /* number of bits in a byte */
64 * Select uses bit masks of file descriptors in longs.
65 * These macros manipulate such bit fields (the filesystem macros use chars).
66 * FD_SETSIZE may be defined by the user, but the default here
67 * should be >= NOFILE (param.h).
70 #define FD_SETSIZE 256
74 #define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
76 #define howmany(x, y) (((x)+((y)-1))/(y))
79 #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
80 #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
81 #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
82 #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
89 struct sockaddr_in hisctladdr
;
90 struct sockaddr_in data_addr
;
95 struct sockaddr_in myctladdr
;
98 off_t restart_point
= 0;
101 int dataconn(char *mode
);
103 int command(char *fmt
, ...);
107 typedef void (*Sig_t
)(int);
111 void psabort(int sig
);
113 char *hookup(char *host
, int port
)
115 register struct hostent
*hp
= 0;
117 static char hostnamebuf
[80];
119 bzero((char *)&hisctladdr
, sizeof (hisctladdr
));
120 hisctladdr
.sin_addr
.s_addr
= inet_addr(host
);
121 if (hisctladdr
.sin_addr
.s_addr
!= -1) {
122 hisctladdr
.sin_family
= AF_INET
;
123 (void) strncpy(hostnamebuf
, host
, sizeof(hostnamebuf
));
125 hp
= gethostbyname(host
);
127 fprintf(stderr
, "ftp: %s: ", host
);
128 herror((char *)NULL
);
132 hisctladdr
.sin_family
= hp
->h_addrtype
;
133 bcopy(hp
->h_addr_list
[0],
134 (caddr_t
)&hisctladdr
.sin_addr
, hp
->h_length
);
135 (void) strncpy(hostnamebuf
, hp
->h_name
, sizeof(hostnamebuf
));
137 hostname
= hostnamebuf
;
138 s
= socket(hisctladdr
.sin_family
, SOCK_STREAM
, 0);
140 perror("ftp: socket");
144 hisctladdr
.sin_port
= port
;
145 while (connect(s
, (struct sockaddr
*)&hisctladdr
, sizeof (hisctladdr
)) < 0) {
146 if (hp
&& hp
->h_addr_list
[1]) {
149 fprintf(stderr
, "ftp: connect to address %s: ",
150 inet_ntoa(hisctladdr
.sin_addr
));
154 bcopy(hp
->h_addr_list
[0],
155 (caddr_t
)&hisctladdr
.sin_addr
, hp
->h_length
);
156 fprintf(stdout
, "Trying %s...\n",
157 inet_ntoa(hisctladdr
.sin_addr
));
158 (void) fflush(stdout
);
160 s
= socket(hisctladdr
.sin_family
, SOCK_STREAM
, 0);
162 perror("ftp: socket");
168 perror("ftp: connect");
172 len
= sizeof (myctladdr
);
173 if (getsockname(s
, (struct sockaddr
*)&myctladdr
, &len
) < 0) {
174 perror("ftp: getsockname");
180 printf("Connected to %s.\n", hostname
);
181 (void) fflush(stdout
);
183 if (getreply(0) > 2) { /* read startup message from server */
192 if (setsockopt(s
, SOL_SOCKET
, SO_OOBINLINE
, (const char *) &on
, sizeof(on
))
194 perror("ftp: setsockopt");
197 #endif //SO_OOBINLINE
205 int login(char *host
)
208 char *user
, *pass
, *acct
;
211 user
= pass
= acct
= 0;
212 if (ruserpass(host
, &user
, &pass
, &acct
) < 0) {
216 while (user
== NULL
) {
217 char *myname
= "none"; // This needs to become the usename env
220 printf("Name (%s:%s): ", host
, myname
);
222 printf("Name (%s): ", host
);
223 (void) fflush(stdout
);
224 (void) fgets(tmp
, sizeof(tmp
) - 1, stdin
);
225 tmp
[strlen(tmp
) - 1] = '\0';
231 n
= command("USER %s", user
);
234 pass
= getpass("Password:");
235 n
= command("PASS %s", pass
);
240 acct
= getpass("Account:");
241 n
= command("ACCT %s", acct
);
244 fprintf(stderr
, "Login failed.\n");
247 if (!aflag
&& acct
!= NULL
)
248 (void) command("ACCT %s", acct
);
251 for (n
= 0; n
< macnum
; ++n
) {
252 if (!strcmp("init", macros
[n
].mac_name
)) {
253 (void) strcpy(line
, "$init");
255 domacro(margc
, margv
);
265 extern jmp_buf ptabort
;
268 (void) fflush(stdout
);
275 int command(char *fmt
, ...)
279 void (*oldintr
)(int), cmdabort(int);
285 vfprintf(stdout
, fmt
, ap
);
288 (void) fflush(stdout
);
290 if (cout
== (int) NULL
) {
291 perror ("No control connection for command");
295 oldintr
= signal(SIGINT
,cmdabort
);
300 vsprintf(buffer
, fmt
, ap
);
302 //DLJ: to work through firewalls - send the command as a single message
303 strcat(buffer
,"\r\n");
304 fprintfSocket(cout
, buffer
);
306 //DLJ: the following two lines are replaced by the strcat above - seems to
307 // make it work through firewalls.
308 // fprintfSocket(cout, "\r\n");
309 // (void) fflush(cout);
311 r
= getreply(!strcmp(fmt
, "QUIT"));
312 if (abrtflag
&& oldintr
!= SIG_IGN
)
314 // (void) signal(SIGINT, oldintr);
318 char reply_string
[BUFSIZ
]; /* last line of previous reply */
328 int originalcode
= 0, continuation
= 0;
329 void (*oldintr
)(int), cmdabort(int);
333 oldintr
= signal(SIGINT
,cmdabort
);
337 while ((c
= fgetcSocket(cin
)) != '\n') {
338 if (c
== IAC
) { /* handle telnet commands */
339 switch (c
= fgetcSocket(cin
)) {
342 c
= fgetcSocket(cin
);
343 fprintfSocket(cout
, "%c%c%c",IAC
,DONT
,c
);
347 c
= fgetcSocket(cin
);
348 fprintfSocket(cout
, "%c%c%c",IAC
,WONT
,c
);
358 // (void) signal(SIGINT,oldintr);
364 printf("421 Service not available, remote server has closed connection\n");
365 (void) fflush(stdout
);
370 if (c
!= '\r' && (verbose
> 0 ||
371 (verbose
> -1 && n
== '5' && dig
> 4))) {
373 (dig
== 1 || dig
== 5 && verbose
== 0))
374 printf("%s:",hostname
);
376 (void) fflush(stdout
);
378 if (dig
< 4 && isdigit(c
))
379 code
= code
* 10 + (c
- '0');
380 if (!pflag
&& code
== 227)
382 if (dig
> 4 && pflag
== 1 && isdigit(c
))
385 if (c
!= '\r' && c
!= ')')
392 if (dig
== 4 && c
== '-') {
399 if (cp
< &reply_string
[sizeof(reply_string
) - 1])
402 if (verbose
> 0 || verbose
> -1 && n
== '5') {
404 (void) fflush (stdout
);
406 if (continuation
&& code
!= originalcode
) {
407 if (originalcode
== 0)
414 (void) signal(SIGINT
,oldintr
);
415 if (code
== 421 || originalcode
== 421)
417 if (abrtflag
&& oldintr
!= cmdabort
&& oldintr
!= SIG_IGN
)
429 t
.tv_sec
= (long) sec
;
431 return(select(32, mask
, (struct fd_set
*) 0, (struct fd_set
*) 0, &t
));
441 printf("\nsend aborted\n");
442 (void) fflush(stdout
);
443 longjmp(sendabort
, 1);
446 #define HASHBYTES 1024
448 void sendrequest(char *cmd
, char *local
, char *remote
, int printnames
)
452 int (*closefunc
)(), _pclose(), fclose();
453 sig_t (*oldintr
)(), (*oldintp
)();
455 char buf
[BUFSIZ
], *bufp
;
456 long bytes
= 0, hashbytes
= HASHBYTES
;
459 struct timeval start
, stop
;
462 if (verbose
&& printnames
) {
463 if (local
&& *local
!= '-')
464 printf("local: %s ", local
);
466 printf("remote: %s\n", remote
);
467 (void) fflush(stdout
);
470 proxtrans(cmd
, local
, remote
);
477 if (setjmp(sendabort
)) {
486 null();// (void) signal(SIGINT,oldintr);
488 null();// (void) signal(SIGPIPE,oldintp);
492 null();// oldintr = signal(SIGINT, abortsend);
493 if (strcmp(local
, "-") == 0)
495 else if (*local
== '|') {
496 null();// oldintp = signal(SIGPIPE,SIG_IGN);
497 fin
= _popen(local
+ 1, "r");
500 null();// (void) signal(SIGINT, oldintr);
501 null();// (void) signal(SIGPIPE, oldintp);
507 fin
= fopen(local
, "r");
510 null();// (void) signal(SIGINT, oldintr);
515 if (fstat(fileno(fin
), &st
) < 0 ||
516 (st
.st_mode
&S_IFMT
) != S_IFREG
) {
517 fprintf(stdout
, "%s: not a plain file.\n", local
);
518 (void) fflush(stdout
);
519 null();// (void) signal(SIGINT, oldintr);
526 null();// (void) signal(SIGINT, oldintr);
528 null();// (void) signal(SIGPIPE, oldintp);
530 if (closefunc
!= NULL
)
534 if (setjmp(sendabort
))
538 (strcmp(cmd
, "STOR") == 0 || strcmp(cmd
, "APPE") == 0)) {
539 if (fseek(fin
, (long) restart_point
, 0) < 0) {
542 if (closefunc
!= NULL
)
546 if (command("REST %ld", (long) restart_point
)
549 if (closefunc
!= NULL
)
557 if (command("%s %s", cmd
, remote
) != PRELIM
) {
558 null();// (void) signal(SIGINT, oldintr);
560 null();// (void) signal(SIGPIPE, oldintp);
561 if (closefunc
!= NULL
)
566 if (command("%s", cmd
) != PRELIM
) {
567 null();// (void) signal(SIGINT, oldintr);
569 null();// (void) signal(SIGPIPE, oldintp);
570 if (closefunc
!= NULL
)
574 dout
= dataconn(mode
);
575 if (dout
== (int)NULL
)
577 (void) gettimeofday(&start
, (struct timezone
*)0);
578 null();// oldintp = signal(SIGPIPE, SIG_IGN);
584 while ((c
= read(fileno(fin
), buf
, sizeof (buf
))) > 0) {
586 for (bufp
= buf
; c
> 0; c
-= d
, bufp
+= d
)
587 if ((d
= send(dout
, bufp
, c
, 0)) <= 0)
590 while (bytes
>= hashbytes
) {
592 hashbytes
+= HASHBYTES
;
594 (void) fflush(stdout
);
597 if (hash
&& bytes
> 0) {
598 if (bytes
< HASHBYTES
)
600 (void) putchar('\n');
601 (void) fflush(stdout
);
607 fprintf(stderr
, "netout: write returned 0?\n");
608 else if (errno
!= EPIPE
)
617 static int bufsize
= 1024;
620 while ((c
= getc(fin
)) != EOF
) {
622 while (hash
&& (bytes
>= hashbytes
)) {
624 (void) fflush(stdout
);
625 hashbytes
+= HASHBYTES
;
627 // Szurgot: The following code is unncessary on Win32.
628 // (void) fputcSocket(dout, '\r');
632 if (ipos
>= bufsize
) {
633 fputSocket(dout
,buf
,ipos
);
634 if(!hash
) (void) putchar('.');
641 fputSocket(dout
,buf
,ipos
);
645 if (bytes
< hashbytes
)
647 (void) putchar('\n');
648 (void) fflush(stdout
);
652 (void) putchar('\n');
653 (void) fflush(stdout
);
657 // if (ferror(dout)) {
658 // if (errno != EPIPE)
665 (void) gettimeofday(&stop
, (struct timezone
*)0);
666 if (closefunc
!= NULL
)
668 if(closesocket(dout
)) {
669 int iret
=WSAGetLastError ();
670 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
671 (void) fflush(stdout
);
674 null();// (void) signal(SIGINT, oldintr);
676 null();// (void) signal(SIGPIPE, oldintp);
678 ptransfer("sent", bytes
, &start
, &stop
);
681 (void) gettimeofday(&stop
, (struct timezone
*)0);
682 null();// (void) signal(SIGINT, oldintr);
684 null();// (void) signal(SIGPIPE, oldintp);
694 if(closesocket(dout
)) {
695 int iret
=WSAGetLastError ();
696 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
697 (void) fflush(stdout
);
702 if (closefunc
!= NULL
&& fin
!= NULL
)
705 ptransfer("sent", bytes
, &start
, &stop
);
717 (void) fflush(stdout
);
718 longjmp(recvabort
, 1);
721 void recvrequest(char *cmd
, char *local
, char *remote
, char *mode
,
726 int (*closefunc
)(), _pclose(), fclose();
727 void (*oldintr
)(int), (*oldintp
)(int);
729 int oldverbose
, oldtype
= 0, is_retr
, tcrflag
, nfnd
, bare_lfs
= 0;
730 char *gunique(), msg
;
731 // static char *buf; // Szurgot: Shouldn't this go SOMEWHERE?
733 static int bufsize
= 1024;
734 long bytes
= 0, hashbytes
= HASHBYTES
;
738 struct timeval start
, stop
;
740 extern void *malloc();
742 is_retr
= strcmp(cmd
, "RETR") == 0;
743 if (is_retr
&& verbose
&& printnames
) {
744 if (local
&& *local
!= '-')
745 printf("local: %s ", local
);
747 printf("remote: %s\n", remote
);
748 (void) fflush(stdout
);
750 if (proxy
&& is_retr
) {
751 proxtrans(cmd
, local
, remote
);
757 tcrflag
= !crflag
&& is_retr
;
758 if (setjmp(recvabort
)) {
767 null();// (void) signal(SIGINT, oldintr);
771 null();// oldintr = signal(SIGINT, abortrecv);
772 if (strcmp(local
, "-") && *local
!= '|') {
774 // This whole thing is a problem... access Won't work on non-existent files
775 if (access(local
, 2) < 0) {
776 char *dir
= rindex(local
, '/');
778 if (errno
!= ENOENT
&& errno
!= EACCES
) {
780 (void) signal(SIGINT
, oldintr
);
786 d
= access(dir
? local
: ".", 2);
791 (void) signal(SIGINT
, oldintr
);
795 if (!runique
&& errno
== EACCES
&&
796 chmod(local
, 0600) < 0) {
798 (void) signal(SIGINT
, oldintr
);
802 if (runique
&& errno
== EACCES
&&
803 (local
= gunique(local
)) == NULL
) {
804 (void) signal(SIGINT
, oldintr
);
809 else if (runique
&& (local
= gunique(local
)) == NULL
) {
810 (void) signal(SIGINT
, oldintr
);
817 null();// (void) signal(SIGINT, oldintr);
821 if (setjmp(recvabort
))
824 if (type
!= TYPE_A
&& (allbinary
== 0 || type
!= TYPE_I
)) {
826 oldverbose
= verbose
;
830 verbose
= oldverbose
;
832 } else if (restart_point
) {
833 if (command("REST %ld", (long) restart_point
) != CONTINUE
)
837 if (command("%s %s", cmd
, remote
) != PRELIM
) {
838 null();// (void) signal(SIGINT, oldintr);
853 verbose
= oldverbose
;
858 if (command("%s", cmd
) != PRELIM
) {
859 null();// (void) signal(SIGINT, oldintr);
874 verbose
= oldverbose
;
880 if (din
== (int)NULL
)
882 if (strcmp(local
, "-") == 0)
884 else if (*local
== '|') {
885 null();// oldintp = signal(SIGPIPE, SIG_IGN);
886 fout
= _popen(local
+ 1, "w");
893 fout
= fopen(local
, mode
);
900 (void) gettimeofday(&start
, (struct timezone
*)0);
906 lseek(fileno(fout
), (long) restart_point
, L_SET
) < 0) {
908 if (closefunc
!= NULL
)
913 // while ((c = recv(din, buf, bufsize, 1)) > 0) {
914 // if ((d = write(fileno(fout), buf, c)) != c)
915 // if ((d = write(fileno(fout), buf, c)) != c)
917 while ((c
= recv(din
, buf
, bufsize
, 0)) > 0) {
918 write(fileno(fout
), buf
, c
);
921 while (bytes
>= hashbytes
) {
923 hashbytes
+= HASHBYTES
;
925 (void) fflush(stdout
);
928 if (hash
&& bytes
> 0) {
929 if (bytes
< HASHBYTES
)
931 (void) putchar('\n');
932 (void) fflush(stdout
);
935 // if (errno != EPIPE)
943 // fprintf(stderr, "%s: short write\n", local);
949 register int i
, n
, c
;
951 if (fseek(fout
, 0L, L_SET
) < 0)
956 if ((c
=getc(fout
)) == EOF
)
961 if (fseek(fout
, 0L, L_INCR
) < 0) {
964 if (closefunc
!= NULL
)
969 while ((c
= fgetcSocket(din
)) != EOF
) {
973 while (hash
&& (bytes
>= hashbytes
)) {
975 (void) fflush(stdout
);
976 hashbytes
+= HASHBYTES
;
979 if ((c
= fgetcSocket(din
)) != '\n' || tcrflag
) {
982 (void) putc('\r', fout
);
991 (void) putc(c
, fout
);
997 printf("WARNING! %d bare linefeeds received in ASCII mode\n");
998 printf("File may not have transferred correctly.\n");
999 (void) fflush(stdout
);
1002 if (bytes
< hashbytes
)
1003 (void) putchar('#');
1004 (void) putchar('\n');
1005 (void) fflush(stdout
);
1007 // if (ferror(din)) {
1008 // if (errno != EPIPE)
1016 if (closefunc
!= NULL
)
1018 null();// (void) signal(SIGINT, oldintr);
1020 null();// (void) signal(SIGPIPE, oldintp);
1021 (void) gettimeofday(&stop
, (struct timezone
*)0);
1022 if(closesocket(din
)) {
1023 int iret
=WSAGetLastError ();
1024 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
1025 (void) fflush(stdout
);
1029 if (bytes
> 0 && is_retr
)
1030 ptransfer("received", bytes
, &start
, &stop
);
1045 verbose
= oldverbose
;
1050 /* abort using RFC959 recommended IP,SYNC sequence */
1052 (void) gettimeofday(&stop
, (struct timezone
*)0);
1054 null();// (void) signal(SIGPIPE, oldintr);
1055 null();// (void) signal(SIGINT,SIG_IGN);
1070 verbose
= oldverbose
;
1074 null();// (void) signal(SIGINT,oldintr);
1078 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1080 /* send IAC in urgent mode instead of DM because UNIX places oob mark */
1081 /* after urgent byte rather than before as now is protocol */
1082 if (send(cout
,&msg
,1,MSG_OOB
) != 1) {
1085 fprintfSocket(cout
,"%cABOR\r\n",DM
);
1087 FD_SET(cin
, &mask
); // Need to correct this
1089 FD_SET(din
, &mask
); // Need to correct this
1091 if ((nfnd
= empty(&mask
,10)) <= 0) {
1098 if (din
&& FD_ISSET(din
, &mask
)) {
1099 while ((c
= recv(din
, buf
, bufsize
, 0)) > 0)
1102 if ((c
= getreply(0)) == ERROR
&& code
== 552) { /* needed for nic style abort */
1115 if (closefunc
!= NULL
&& fout
!= NULL
)
1118 if(closesocket(din
)) {
1119 int iret
=WSAGetLastError ();
1120 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
1121 (void) fflush(stdout
);
1125 ptransfer("received", bytes
, &start
, &stop
);
1126 null();// (void) signal(SIGINT,oldintr);
1130 * Need to start a listen on the data channel
1131 * before we send the command, otherwise the
1132 * server's connect may fail.
1138 register char *p
, *a
;
1139 int result
, len
, tmpno
= 0;
1141 int a0
, a1
, a2
, a3
, p0
, p1
;
1145 data
= socket(AF_INET
, SOCK_STREAM
, 0);
1147 perror("ftp: socket");
1150 if ((options
& SO_DEBUG
) &&
1151 setsockopt(data
, SOL_SOCKET
, SO_DEBUG
, (char *)&on
,
1153 perror("ftp: setsockopt (ignored)");
1154 if (command("PASV") != COMPLETE
) {
1155 printf("Passive mode refused.\n");
1160 * What we've got at this point is a string of comma
1161 * separated one-byte unsigned integer values.
1162 * The first four are the an IP address. The fifth is
1163 * the MSB of the port number, the sixth is the LSB.
1164 * From that we'll prepare a sockaddr_in.
1167 if (sscanf(pasv
,"%d,%d,%d,%d,%d,%d",
1168 &a0
, &a1
, &a2
, &a3
, &p0
, &p1
) != 6) {
1169 printf("Passive mode address scan failure. Shouldn't happen!\n");
1173 bzero(&data_addr
, sizeof(data_addr
));
1174 data_addr
.sin_family
= AF_INET
;
1175 a
= (char *)&data_addr
.sin_addr
.s_addr
;
1180 p
= (char *)&data_addr
.sin_port
;
1184 if (connect(data
, (struct sockaddr
*)&data_addr
,
1185 sizeof(data_addr
)) < 0) {
1186 perror("ftp: connect");
1194 data_addr
= myctladdr
;
1196 data_addr
.sin_port
= 0; /* let system pick one */
1198 (void) close (data
);
1199 data
= socket(AF_INET
, SOCK_STREAM
, 0);
1201 perror("ftp: socket");
1207 if (setsockopt(data
, SOL_SOCKET
, SO_REUSEADDR
, (char *)&on
, sizeof (on
)) < 0) {
1208 perror("ftp: setsockopt (reuse address)");
1211 if (bind(data
, (struct sockaddr
*)&data_addr
, sizeof (data_addr
)) < 0) {
1212 perror("ftp: bind");
1215 if (options
& SO_DEBUG
&&
1216 setsockopt(data
, SOL_SOCKET
, SO_DEBUG
, (char *)&on
, sizeof (on
)) < 0)
1217 perror("ftp: setsockopt (ignored)");
1218 len
= sizeof (data_addr
);
1219 if (getsockname(data
, (struct sockaddr
*)&data_addr
, &len
) < 0) {
1220 perror("ftp: getsockname");
1223 if (listen(data
, 1) < 0)
1224 perror("ftp: listen");
1226 a
= (char *)&data_addr
.sin_addr
;
1227 p
= (char *)&data_addr
.sin_port
;
1228 #define UC(b) (((int)b)&0xff)
1230 command("PORT %d,%d,%d,%d,%d,%d",
1231 UC(a
[0]), UC(a
[1]), UC(a
[2]), UC(a
[3]),
1232 UC(p
[0]), UC(p
[1]));
1233 if (result
== ERROR
&& sendport
== -1) {
1238 return (result
!= COMPLETE
);
1244 (void) fflush(stdout
);
1245 (void) close(data
), data
= -1;
1251 int dataconn(char *mode
)
1253 struct sockaddr_in from
;
1254 int s
, fromlen
= sizeof (from
);
1259 s
= accept(data
, (struct sockaddr
*) &from
, &fromlen
);
1261 perror("ftp: accept");
1262 (void) closesocket(data
), data
= -1;
1263 return (int) (NULL
);
1265 if(closesocket(data
)) {
1266 int iret
=WSAGetLastError ();
1267 fprintf(stdout
,"Error closing socket(%d)\n",iret
);
1268 (void) fflush(stdout
);
1275 void ptransfer(direction
, bytes
, t0
, t1
)
1278 struct timeval
*t0
, *t1
;
1285 s
= td
.tv_sec
+ (td
.tv_usec
/ 1000000.);
1286 #define nz(x) ((x) == 0 ? 1 : (x))
1288 printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
1289 bytes
, direction
, s
, bs
/ 1024.);
1290 (void) fflush(stdout
);
1295 struct timeval *tsum, *t0;
1298 tsum->tv_sec += t0->tv_sec;
1299 tsum->tv_usec += t0->tv_usec;
1300 if (tsum->tv_usec > 1000000)
1301 tsum->tv_sec++, tsum->tv_usec -= 1000000;
1304 void tvsub(tdiff
, t1
, t0
)
1305 struct timeval
*tdiff
, *t1
, *t0
;
1308 tdiff
->tv_sec
= t1
->tv_sec
- t0
->tv_sec
;
1309 tdiff
->tv_usec
= t1
->tv_usec
- t0
->tv_usec
;
1310 if (tdiff
->tv_usec
< 0)
1311 tdiff
->tv_sec
--, tdiff
->tv_usec
+= 1000000;
1314 void psabort(int flag
)
1316 extern int abrtflag
;
1321 void pswitch(int flag
)
1323 extern int proxy
, abrtflag
;
1325 static struct comvars
{
1327 char name
[MAXHOSTNAMELEN
];
1328 struct sockaddr_in mctl
;
1329 struct sockaddr_in hctl
;
1341 char mi
[MAXPATHLEN
];
1342 char mo
[MAXPATHLEN
];
1343 } proxstruct
, tmpstruct
;
1344 struct comvars
*ip
, *op
;
1347 oldintr
= signal(SIGINT
, psabort
);
1362 ip
->connect
= connected
;
1363 connected
= op
->connect
;
1365 (void) strncpy(ip
->name
, hostname
, sizeof(ip
->name
) - 1);
1366 ip
->name
[strlen(ip
->name
)] = '\0';
1369 hostname
= op
->name
;
1370 ip
->hctl
= hisctladdr
;
1371 hisctladdr
= op
->hctl
;
1372 ip
->mctl
= myctladdr
;
1373 myctladdr
= op
->mctl
;
1374 (int) ip
->in
= cin
; // What the hell am I looking at...?
1376 (int) ip
->out
= cout
; // Same again...
1377 cout
= (int) op
->out
;
1384 ip
->sunqe
= sunique
;
1385 sunique
= op
->sunqe
;
1386 ip
->runqe
= runique
;
1387 runique
= op
->runqe
;
1392 (void) strncpy(ip
->nti
, ntin
, 16);
1393 (ip
->nti
)[strlen(ip
->nti
)] = '\0';
1394 (void) strcpy(ntin
, op
->nti
);
1395 (void) strncpy(ip
->nto
, ntout
, 16);
1396 (ip
->nto
)[strlen(ip
->nto
)] = '\0';
1397 (void) strcpy(ntout
, op
->nto
);
1398 ip
->mapflg
= mapflag
;
1399 mapflag
= op
->mapflg
;
1400 (void) strncpy(ip
->mi
, mapin
, MAXPATHLEN
- 1);
1401 (ip
->mi
)[strlen(ip
->mi
)] = '\0';
1402 (void) strcpy(mapin
, op
->mi
);
1403 (void) strncpy(ip
->mo
, mapout
, MAXPATHLEN
- 1);
1404 (ip
->mo
)[strlen(ip
->mo
)] = '\0';
1405 (void) strcpy(mapout
, op
->mo
);
1406 // (void) signal(SIGINT, oldintr);
1420 (void) fflush(stdout
);
1424 longjmp(ptabort
, 1);
1427 void proxtrans(cmd
, local
, remote
)
1428 char *cmd
, *local
, *remote
;
1430 // void (*oldintr)(int);
1431 //void abortpt(int);
1432 int tmptype
, oldtype
= 0, secndflag
= 0, nfnd
;
1433 extern jmp_buf ptabort
;
1438 if (strcmp(cmd
, "RETR"))
1441 cmd2
= runique
? "STOU" : "STOR";
1442 if (command("PASV") != COMPLETE
) {
1443 printf("proxy server does not support third part transfers.\n");
1444 (void) fflush(stdout
);
1450 printf("No primary connection\n");
1451 (void) fflush(stdout
);
1456 if (type
!= tmptype
) {
1473 if (command("PORT %s", pasv
) != COMPLETE
) {
1493 if (setjmp(ptabort
))
1495 null();// oldintr = signal(SIGINT, abortpt);
1496 if (command("%s %s", cmd
, remote
) != PRELIM
) {
1497 null();// (void) signal(SIGINT, oldintr);
1520 if (command("%s %s", cmd2
, local
) != PRELIM
)
1526 null();// (void) signal(SIGINT, oldintr);
1545 printf("local: %s remote: %s\n", local
, remote
);
1546 (void) fflush(stdout
);
1549 null();// (void) signal(SIGINT, SIG_IGN);
1551 if (strcmp(cmd
, "RETR") && !proxy
)
1553 else if (!strcmp(cmd
, "RETR") && proxy
)
1555 if (!cpend
&& !secndflag
) { /* only here if cmd = "STOR" (proxy=1) */
1556 if (command("%s %s", cmd2
, local
) != PRELIM
) {
1577 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1579 *(msg
+1) = (char) DM
;
1580 if (send(cout
,msg
,2,MSG_OOB
) != 2)
1582 fprintfSocket(cout
,"ABOR\r\n");
1584 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this
1585 if ((nfnd
= empty(&mask
,10)) <= 0) {
1600 null();// (void) signal(SIGINT, oldintr);
1606 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1608 *(msg
+1) = (char)DM
;
1609 if (send(cout
,msg
,2,MSG_OOB
) != 2)
1611 fprintfSocket(cout
,"ABOR\r\n");
1613 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this...
1614 if ((nfnd
= empty(&mask
,10)) <= 0) {
1626 if (!cpend
&& !secndflag
) { /* only if cmd = "RETR" (proxy=1) */
1627 if (command("%s %s", cmd2
, local
) != PRELIM
) {
1648 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1650 *(msg
+1) = (char)DM
;
1651 if (send(cout
,msg
,2,MSG_OOB
) != 2)
1653 fprintfSocket(cout
,"ABOR\r\n");
1655 // FD_SET(fileno(cin), &mask); // Chris:
1656 if ((nfnd
= empty(&mask
,10)) <= 0) {
1670 null();// (void) signal(SIGINT, oldintr);
1677 fprintfSocket(cout
,"%c%c",IAC
,IP
);
1679 *(msg
+1) = (char)DM
;
1680 if (send(cout
,msg
,2,MSG_OOB
) != 2)
1682 fprintfSocket(cout
,"ABOR\r\n");
1684 // FD_SET(fileno(cin), &mask); // Chris:
1685 if ((nfnd
= empty(&mask
,10)) <= 0) {
1699 // FD_SET(fileno(cin), &mask); // Chris:
1700 if ((nfnd
= empty(&mask
,10)) <= 0) {
1732 null();// (void) signal(SIGINT, oldintr);
1743 // FD_SET(fileno(cin), &mask); // Chris
1744 if ((nfnd
= empty(&mask
,0)) < 0) {
1759 static char new[MAXPATHLEN
];
1760 char *cp
= rindex(local
, '/');
1766 d
= access(cp
? local
: ".", 2);
1773 (void) strcpy(new, local
);
1774 cp
= new + strlen(new);
1777 if (++count
== 100) {
1778 printf("runique: can't find unique file name.\n");
1779 (void) fflush(stdout
);
1788 if ((d
= access(new, 0)) < 0)
1792 else if (*(cp
- 2) == '.')
1795 *(cp
- 2) = *(cp
- 2) + 1;