new file organization
[unix-history] / usr / src / usr.bin / ftp / ftp.c
index 57c7b3e..ae2b804 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)ftp.c      4.5 (Berkeley) %G%";
+static char sccsid[] = "@(#)ftp.c      4.9 (Berkeley) %G%";
 #endif
 
 #include <sys/param.h>
 #endif
 
 #include <sys/param.h>
@@ -8,6 +8,7 @@ static char sccsid[] = "@(#)ftp.c       4.5 (Berkeley) %G%";
 #include <sys/socket.h>
 
 #include <netinet/in.h>
 #include <sys/socket.h>
 
 #include <netinet/in.h>
+#include <arpa/ftp.h>
 
 #include <stdio.h>
 #include <signal.h>
 
 #include <stdio.h>
 #include <signal.h>
@@ -15,7 +16,6 @@ static char sccsid[] = "@(#)ftp.c     4.5 (Berkeley) %G%";
 #include <errno.h>
 #include <netdb.h>
 
 #include <errno.h>
 #include <netdb.h>
 
-#include "ftp.h"
 #include "ftp_var.h"
 
 struct sockaddr_in hisctladdr;
 #include "ftp_var.h"
 
 struct sockaddr_in hisctladdr;
@@ -33,7 +33,7 @@ hookup(host, port)
        int port;
 {
        register struct hostent *hp;
        int port;
 {
        register struct hostent *hp;
-       int s;
+       int s, len;
 
        bzero((char *)&hisctladdr, sizeof (hisctladdr));
        hp = gethostbyname(host);
 
        bzero((char *)&hisctladdr, sizeof (hisctladdr));
        hp = gethostbyname(host);
@@ -74,8 +74,9 @@ hookup(host, port)
                perror("ftp: connect");
                goto bad;
        }
                perror("ftp: connect");
                goto bad;
        }
-       if (socketaddr(s, &myctladdr) < 0) {
-               perror("ftp: socketaddr");
+       len = sizeof (myctladdr);
+       if (getsockname(s, (char *)&myctladdr, &len) < 0) {
+               perror("ftp: getsockname");
                goto bad;
        }
        cin = fdopen(s, "r");
                goto bad;
        }
        cin = fdopen(s, "r");
@@ -189,7 +190,7 @@ getreply(expecteof)
 empty(f)
        FILE *f;
 {
 empty(f)
        FILE *f;
 {
-       int mask;
+       long mask;
        struct timeval t;
 
        if (f->_cnt > 0)
        struct timeval t;
 
        if (f->_cnt > 0)
@@ -214,7 +215,7 @@ sendrequest(cmd, local, remote)
        FILE *fin, *dout, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)();
        char buf[BUFSIZ];
        FILE *fin, *dout, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)();
        char buf[BUFSIZ];
-       register int bytes = 0;
+       long bytes = 0, hashbytes = sizeof (buf);
        register int c, d;
        struct stat st;
        struct timeval start, stop;
        register int c, d;
        struct stat st;
        struct timeval start, stop;
@@ -266,6 +267,14 @@ sendrequest(cmd, local, remote)
                        if ((d = write(fileno (dout), buf, c)) < 0)
                                break;
                        bytes += c;
                        if ((d = write(fileno (dout), buf, c)) < 0)
                                break;
                        bytes += c;
+                       if (hash) {
+                               putchar('#');
+                               fflush(stdout);
+                       }
+               }
+               if (hash && bytes > 0) {
+                       putchar('\n');
+                       fflush(stdout);
                }
                if (c < 0)
                        perror(local);
                }
                if (c < 0)
                        perror(local);
@@ -276,6 +285,11 @@ sendrequest(cmd, local, remote)
        case TYPE_A:
                while ((c = getc(fin)) != EOF) {
                        if (c == '\n') {
        case TYPE_A:
                while ((c = getc(fin)) != EOF) {
                        if (c == '\n') {
+                               while (hash && (bytes >= hashbytes)) {
+                                       putchar('#');
+                                       fflush(stdout);
+                                       hashbytes += sizeof (buf);
+                               }
                                if (ferror(dout))
                                        break;
                                putc('\r', dout);
                                if (ferror(dout))
                                        break;
                                putc('\r', dout);
@@ -288,6 +302,12 @@ sendrequest(cmd, local, remote)
                                bytes++;
                        }
                }
                                bytes++;
                        }
                }
+               if (hash) {
+                       if (bytes < hashbytes)
+                               putchar('#');
+                       putchar('\n');
+                       fflush(stdout);
+               }
                if (ferror(fin))
                        perror(local);
                if (ferror(dout))
                if (ferror(fin))
                        perror(local);
                if (ferror(dout))
@@ -320,13 +340,13 @@ abortrecv()
        longjmp(recvabort, 1);
 }
 
        longjmp(recvabort, 1);
 }
 
-recvrequest(cmd, local, remote)
-       char *cmd, *local, *remote;
+recvrequest(cmd, local, remote, mode)
+       char *cmd, *local, *remote, *mode;
 {
        FILE *fout, *din, *popen();
 {
        FILE *fout, *din, *popen();
-       char buf[BUFSIZ];
        int (*closefunc)(), pclose(), fclose(), (*oldintr)();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)();
-       register int bytes = 0;
+       char buf[BUFSIZ];
+       long bytes = 0, hashbytes = sizeof (buf);
        register int c, d;
        struct timeval start, stop;
 
        register int c, d;
        struct timeval start, stop;
 
@@ -361,7 +381,7 @@ recvrequest(cmd, local, remote)
                fout = popen(local + 1, "w");
                closefunc = pclose;
        } else {
                fout = popen(local + 1, "w");
                closefunc = pclose;
        } else {
-               fout = fopen(local, "w");
+               fout = fopen(local, mode);
                closefunc = fclose;
        }
        if (fout == NULL) {
                closefunc = fclose;
        }
        if (fout == NULL) {
@@ -381,6 +401,14 @@ recvrequest(cmd, local, remote)
                        if ((d = write(fileno(fout), buf, c)) < 0)
                                break;
                        bytes += c;
                        if ((d = write(fileno(fout), buf, c)) < 0)
                                break;
                        bytes += c;
+                       if (hash) {
+                               putchar('#');
+                               fflush(stdout);
+                       }
+               }
+               if (hash && bytes > 0) {
+                       putchar('\n');
+                       fflush(stdout);
                }
                if (c < 0)
                        perror("netin");
                }
                if (c < 0)
                        perror("netin");
@@ -391,6 +419,11 @@ recvrequest(cmd, local, remote)
        case TYPE_A:
                while ((c = getc(din)) != EOF) {
                        if (c == '\r') {
        case TYPE_A:
                while ((c = getc(din)) != EOF) {
                        if (c == '\r') {
+                               while (hash && (bytes >= hashbytes)) {
+                                       putchar('#');
+                                       fflush(stdout);
+                                       hashbytes += sizeof (buf);
+                               }
                                bytes++;
                                if ((c = getc(din)) != '\n') {
                                        if (ferror (fout))
                                bytes++;
                                if ((c = getc(din)) != '\n') {
                                        if (ferror (fout))
@@ -405,6 +438,12 @@ recvrequest(cmd, local, remote)
                        putc (c, fout);
                        bytes++;
                }
                        putc (c, fout);
                        bytes++;
                }
+               if (hash) {
+                       if (bytes < hashbytes)
+                               putchar('#');
+                       putchar('\n');
+                       fflush(stdout);
+               }
                if (ferror (din))
                        perror ("netin");
                if (ferror (fout))
                if (ferror (din))
                        perror ("netin");
                if (ferror (fout))
@@ -434,18 +473,29 @@ bad:
  * before we send the command, otherwise the
  * server's connect may fail.
  */
  * before we send the command, otherwise the
  * server's connect may fail.
  */
+static int sendport = -1;
+
 initconn()
 {
        register char *p, *a;
 initconn()
 {
        register char *p, *a;
-       int result;
+       int result, len;
 
 
+noport:
        data_addr = myctladdr;
        data_addr = myctladdr;
-       data_addr.sin_port = 0;         /* let system pick one */
+       if (sendport)
+               data_addr.sin_port = 0; /* let system pick one */ 
+       if (data != -1)
+               (void) close (data);
        data = socket(AF_INET, SOCK_STREAM, 0, 0);
        if (data < 0) {
                perror("ftp: socket");
                return (1);
        }
        data = socket(AF_INET, SOCK_STREAM, 0, 0);
        if (data < 0) {
                perror("ftp: socket");
                return (1);
        }
+       if (!sendport)
+               if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) {
+                       perror("ftp: setsockopt (resuse address)");
+                       goto bad;
+               }
        if (bind(data, (char *)&data_addr, sizeof (data_addr), 0) < 0) {
                perror("ftp: bind");
                goto bad;
        if (bind(data, (char *)&data_addr, sizeof (data_addr), 0) < 0) {
                perror("ftp: bind");
                goto bad;
@@ -453,22 +503,30 @@ initconn()
        if (options & SO_DEBUG &&
            setsockopt(data, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
                perror("ftp: setsockopt (ignored)");
        if (options & SO_DEBUG &&
            setsockopt(data, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
                perror("ftp: setsockopt (ignored)");
-       if (socketaddr(data, &data_addr) < 0) {
-               perror("ftp: socketaddr");
+       len = sizeof (data_addr);
+       if (getsockname(data, (char *)&data_addr, &len) < 0) {
+               perror("ftp: getsockname");
                goto bad;
        }
        if (listen(data, 1) < 0) {
                perror("ftp: listen");
                goto bad;
        }
                goto bad;
        }
        if (listen(data, 1) < 0) {
                perror("ftp: listen");
                goto bad;
        }
-       a = (char *)&data_addr.sin_addr;
-       p = (char *)&data_addr.sin_port;
+       if (sendport) {
+               a = (char *)&data_addr.sin_addr;
+               p = (char *)&data_addr.sin_port;
 #define        UC(b)   (((int)b)&0xff)
 #define        UC(b)   (((int)b)&0xff)
-       result =
-           command("PORT %d,%d,%d,%d,%d,%d",
-             UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
-             UC(p[0]), UC(p[1]));
-       return (result != COMPLETE);
+               result =
+                   command("PORT %d,%d,%d,%d,%d,%d",
+                     UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
+                     UC(p[0]), UC(p[1]));
+               if (result == ERROR && sendport == -1) {
+                       sendport = 0;
+                       goto noport;
+               }
+               return (result != COMPLETE);
+       }
+       return (0);
 bad:
        (void) close(data), data = -1;
        return (1);
 bad:
        (void) close(data), data = -1;
        return (1);
@@ -489,24 +547,27 @@ dataconn(mode)
        }
        (void) close(data);
        data = s;
        }
        (void) close(data);
        data = s;
+       if (*mode == 'w' && linger)
+               (void) setsockopt(s, SOL_SOCKET, SO_LINGER, &linger,
+                   sizeof (linger));
        return (fdopen(data, mode));
 }
 
 ptransfer(direction, bytes, t0, t1)
        char *direction;
        return (fdopen(data, mode));
 }
 
 ptransfer(direction, bytes, t0, t1)
        char *direction;
-       int bytes;
+       long bytes;
        struct timeval *t0, *t1;
 {
        struct timeval td;
        struct timeval *t0, *t1;
 {
        struct timeval td;
-       int ms, bs;
+       long ms;
+       float bs;
 
        tvsub(&td, t1, t0);
        ms = (td.tv_sec * 1000) + (td.tv_usec / 1000);
 #define        nz(x)   ((x) == 0 ? 1 : (x))
 
        tvsub(&td, t1, t0);
        ms = (td.tv_sec * 1000) + (td.tv_usec / 1000);
 #define        nz(x)   ((x) == 0 ? 1 : (x))
-       bs = ((bytes * NBBY * 1000) / nz(ms)) / NBBY;
-       printf("%d bytes %s in %d.%02d seconds (%d.%01d Kbytes/s)\n",
-               bytes, direction, td.tv_sec, td.tv_usec / 10000,
-               bs / 1024, (((bs % 1024) * 10) + 1023) / 1024);
+       bs = ((bytes * NBBY * 1000) / (float) nz(ms)) / NBBY;
+       printf("%ld bytes %s in %d.%02d seconds (%.2g Kbytes/s)\n",
+               bytes, direction, td.tv_sec, td.tv_usec / 10000, bs / 1024.);
 }
 
 tvadd(tsum, t0)
 }
 
 tvadd(tsum, t0)