remove unused setebcdic() to make lint happier
[unix-history] / usr / src / usr.bin / ftp / ftp.c
index 433a71d..7a4986b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1985 Regents of the University of California.
+ * Copyright (c) 1985, 1989 Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ftp.c      5.24 (Berkeley) %G%";
+static char sccsid[] = "@(#)ftp.c      5.31 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -36,6 +36,7 @@ static char sccsid[] = "@(#)ftp.c     5.24 (Berkeley) %G%";
 #include <netdb.h>
 #include <fcntl.h>
 #include <pwd.h>
 #include <netdb.h>
 #include <fcntl.h>
 #include <pwd.h>
+#include <varargs.h>
 
 #include "ftp_var.h"
 
 
 #include "ftp_var.h"
 
@@ -47,7 +48,10 @@ int  ptflag = 0;
 int    connected;
 struct sockaddr_in myctladdr;
 uid_t  getuid();
 int    connected;
 struct sockaddr_in myctladdr;
 uid_t  getuid();
-off_t  restart_point = 0;
+sig_t  lostpeer();
+
+extern char *strerror();
+extern int errno;
 
 FILE   *cin, *cout;
 FILE   *dataconn();
 
 FILE   *cin, *cout;
 FILE   *dataconn();
@@ -87,9 +91,10 @@ hookup(host, port)
                return (0);
        }
        hisctladdr.sin_port = port;
                return (0);
        }
        hisctladdr.sin_port = port;
-       while (connect(s, &hisctladdr, sizeof (hisctladdr)) < 0) {
+       while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
                if (hp && hp->h_addr_list[1]) {
                        int oerrno = errno;
                if (hp && hp->h_addr_list[1]) {
                        int oerrno = errno;
+                       extern char *inet_ntoa();
 
                        fprintf(stderr, "ftp: connect to address %s: ",
                                inet_ntoa(hisctladdr.sin_addr));
 
                        fprintf(stderr, "ftp: connect to address %s: ",
                                inet_ntoa(hisctladdr.sin_addr));
@@ -114,7 +119,7 @@ hookup(host, port)
                goto bad;
        }
        len = sizeof (myctladdr);
                goto bad;
        }
        len = sizeof (myctladdr);
-       if (getsockname(s, (char *)&myctladdr, &len) < 0) {
+       if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
                perror("ftp: getsockname");
                code = -1;
                goto bad;
                perror("ftp: getsockname");
                code = -1;
                goto bad;
@@ -149,7 +154,7 @@ hookup(host, port)
                        perror("ftp: setsockopt");
                }
        }
                        perror("ftp: setsockopt");
                }
        }
-#endif SO_OOBINLINE
+#endif /* SO_OOBINLINE */
 
        return (hostname);
 bad:
 
        return (hostname);
 bad:
@@ -169,7 +174,7 @@ login(host)
                code = -1;
                return(0);
        }
                code = -1;
                return(0);
        }
-       if (user == NULL) {
+       while (user == NULL) {
                char *myname = getlogin();
 
                if (myname == NULL) {
                char *myname = getlogin();
 
                if (myname == NULL) {
@@ -178,7 +183,10 @@ login(host)
                        if (pp != NULL)
                                myname = pp->pw_name;
                }
                        if (pp != NULL)
                                myname = pp->pw_name;
                }
-               printf("Name (%s:%s): ", host, myname);
+               if (myname)
+                       printf("Name (%s:%s): ", host, myname);
+               else
+                       printf("Name (%s): ", host);
                (void) fgets(tmp, sizeof(tmp) - 1, stdin);
                tmp[strlen(tmp) - 1] = '\0';
                if (*tmp == '\0')
                (void) fgets(tmp, sizeof(tmp) - 1, stdin);
                tmp[strlen(tmp) - 1] = '\0';
                if (*tmp == '\0')
@@ -216,6 +224,7 @@ login(host)
        return (1);
 }
 
        return (1);
 }
 
+sig_t
 cmdabort()
 {
        extern jmp_buf ptabort;
 cmdabort()
 {
        extern jmp_buf ptabort;
@@ -227,16 +236,25 @@ cmdabort()
                longjmp(ptabort,1);
 }
 
                longjmp(ptabort,1);
 }
 
-/*VARARGS1*/
-command(fmt, args)
-       char *fmt;
+/*VARARGS*/
+command(va_alist)
+va_dcl
 {
 {
-       int r, (*oldintr)(), cmdabort();
+       va_list ap;
+       char *fmt;
+       int r;
+       sig_t (*oldintr)(), cmdabort();
 
        abrtflag = 0;
        if (debug) {
                printf("---> ");
 
        abrtflag = 0;
        if (debug) {
                printf("---> ");
-               _doprnt(fmt, &args, stdout);
+               va_start(ap);
+               fmt = va_arg(ap, char *);
+               if (strncmp("PASS ", fmt, 5) == 0)
+                       printf("PASS XXXX");
+               else 
+                       vfprintf(stdout, fmt, ap);
+               va_end(ap);
                printf("\n");
                (void) fflush(stdout);
        }
                printf("\n");
                (void) fflush(stdout);
        }
@@ -245,8 +263,11 @@ command(fmt, args)
                code = -1;
                return (0);
        }
                code = -1;
                return (0);
        }
-       oldintr = signal(SIGINT,cmdabort);
-       _doprnt(fmt, &args, cout);
+       oldintr = signal(SIGINT, cmdabort);
+       va_start(ap);
+       fmt = va_arg(ap, char *);
+       vfprintf(cout, fmt, ap);
+       va_end(ap);
        fprintf(cout, "\r\n");
        (void) fflush(cout);
        cpend = 1;
        fprintf(cout, "\r\n");
        (void) fflush(cout);
        cpend = 1;
@@ -257,7 +278,7 @@ command(fmt, args)
        return(r);
 }
 
        return(r);
 }
 
-char reply_string[BUFSIZ];
+char reply_string[BUFSIZ];             /* last line of previous reply */
 
 #include <ctype.h>
 
 
 #include <ctype.h>
 
@@ -267,27 +288,28 @@ getreply(expecteof)
        register int c, n;
        register int dig;
        register char *cp;
        register int c, n;
        register int dig;
        register char *cp;
-       int originalcode = 0, continuation = 0, (*oldintr)(), cmdabort();
+       int originalcode = 0, continuation = 0;
+       sig_t (*oldintr)(), cmdabort();
        int pflag = 0;
        char *pt = pasv;
 
        int pflag = 0;
        char *pt = pasv;
 
-       cp = reply_string;
-       oldintr = signal(SIGINT,cmdabort);
+       oldintr = signal(SIGINT, cmdabort);
        for (;;) {
                dig = n = code = 0;
        for (;;) {
                dig = n = code = 0;
+               cp = reply_string;
                while ((c = getc(cin)) != '\n') {
                        if (c == IAC) {     /* handle telnet commands */
                                switch (c = getc(cin)) {
                                case WILL:
                                case WONT:
                                        c = getc(cin);
                while ((c = getc(cin)) != '\n') {
                        if (c == IAC) {     /* handle telnet commands */
                                switch (c = getc(cin)) {
                                case WILL:
                                case WONT:
                                        c = getc(cin);
-                                       fprintf(cout, "%c%c%c",IAC,DONT,c);
+                                       fprintf(cout, "%c%c%c", IAC, DONT, c);
                                        (void) fflush(cout);
                                        break;
                                case DO:
                                case DONT:
                                        c = getc(cin);
                                        (void) fflush(cout);
                                        break;
                                case DO:
                                case DONT:
                                        c = getc(cin);
-                                       fprintf(cout, "%c%c%c",IAC,WONT,c);
+                                       fprintf(cout, "%c%c%c", IAC, WONT, c);
                                        (void) fflush(cout);
                                        break;
                                default:
                                        (void) fflush(cout);
                                        break;
                                default:
@@ -338,7 +360,8 @@ getreply(expecteof)
                        }
                        if (n == 0)
                                n = c;
                        }
                        if (n == 0)
                                n = c;
-                       *cp++ = c;
+                       if (cp < &reply_string[sizeof(reply_string) - 1])
+                               *cp++ = c;
                }
                if (verbose > 0 || verbose > -1 && n == '5') {
                        (void) putchar(c);
                }
                if (verbose > 0 || verbose > -1 && n == '5') {
                        (void) putchar(c);
@@ -379,30 +402,40 @@ abortsend()
 
        mflag = 0;
        abrtflag = 0;
 
        mflag = 0;
        abrtflag = 0;
-       printf("\nsend aborted\n");
+       printf("\nsend aborted\nwaiting for remote to finish abort\n");
        (void) fflush(stdout);
        longjmp(sendabort, 1);
 }
 
 #define HASHBYTES 1024
 
        (void) fflush(stdout);
        longjmp(sendabort, 1);
 }
 
 #define HASHBYTES 1024
 
-sendrequest(cmd, local, remote)
+sendrequest(cmd, local, remote, printnames)
        char *cmd, *local, *remote;
        char *cmd, *local, *remote;
+       int printnames;
 {
        FILE *fin, *dout = 0, *popen();
 {
        FILE *fin, *dout = 0, *popen();
-       int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)();
+       int (*closefunc)(), pclose(), fclose();
+       sig_t (*oldintr)(), (*oldintp)();
        int abortsend();
        int abortsend();
-       char buf[BUFSIZ];
+       char buf[BUFSIZ], *bufp;
        long bytes = 0, hashbytes = HASHBYTES;
        register int c, d;
        struct stat st;
        struct timeval start, stop;
        char *mode;
 
        long bytes = 0, hashbytes = HASHBYTES;
        register int c, d;
        struct stat st;
        struct timeval start, stop;
        char *mode;
 
+       if (verbose && printnames) {
+               if (local && *local != '-')
+                       printf("local: %s ", local);
+               if (remote)
+                       printf("remote: %s\n", remote);
+       }
        if (proxy) {
                proxtrans(cmd, local, remote);
                return;
        }
        if (proxy) {
                proxtrans(cmd, local, remote);
                return;
        }
+       if (curtype != type)
+               changetype(type, 0);
        closefunc = NULL;
        oldintr = NULL;
        oldintp = NULL;
        closefunc = NULL;
        oldintr = NULL;
        oldintp = NULL;
@@ -439,7 +472,8 @@ sendrequest(cmd, local, remote)
        } else {
                fin = fopen(local, "r");
                if (fin == NULL) {
        } else {
                fin = fopen(local, "r");
                if (fin == NULL) {
-                       perror(local);
+                       fprintf(stderr, "local: %s: %s\n", local,
+                               strerror(errno));
                        (void) signal(SIGINT, oldintr);
                        code = -1;
                        return;
                        (void) signal(SIGINT, oldintr);
                        code = -1;
                        return;
@@ -466,26 +500,6 @@ sendrequest(cmd, local, remote)
        if (setjmp(sendabort))
                goto abort;
 
        if (setjmp(sendabort))
                goto abort;
 
-       if (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0) {
-               if (restart_point) {
-                       if (fseek(fin, (long) restart_point, 0) < 0) {
-                               perror(local);
-                               restart_point = 0;
-                               if (closefunc != NULL)
-                                       (*closefunc)(fin);
-                               return;
-                       }
-                       if (command("REST %ld", (long) restart_point)
-                               != CONTINUE) {
-                               restart_point = 0;
-                               if (closefunc != NULL)
-                                       (*closefunc)(fin);
-                               return;
-                       }
-                       restart_point = 0;
-                       mode = "r+w";
-               }
-       }
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
@@ -514,10 +528,14 @@ sendrequest(cmd, local, remote)
        case TYPE_I:
        case TYPE_L:
                errno = d = 0;
        case TYPE_I:
        case TYPE_L:
                errno = d = 0;
-               while ((c = read(fileno (fin), buf, sizeof (buf))) > 0) {
-                       if ((d = write(fileno (dout), buf, c)) != c)
-                               break;
+               while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
                        bytes += c;
                        bytes += c;
+                       for (bufp = buf; c > 0; c -= d, bufp += d)
+                               if ((d = write(fileno(dout), bufp, c)) <= 0)
+                                       break;
+                       for (bufp = buf; c > 0; c -= d, bufp += d)
+                               if ((d = write(fileno(dout), bufp, c)) <= 0)
+                                       break;
                        if (hash) {
                                while (bytes >= hashbytes) {
                                        (void) putchar('#');
                        if (hash) {
                                while (bytes >= hashbytes) {
                                        (void) putchar('#');
@@ -533,9 +551,12 @@ sendrequest(cmd, local, remote)
                        (void) fflush(stdout);
                }
                if (c < 0)
                        (void) fflush(stdout);
                }
                if (c < 0)
-                       perror(local);
-               if (d < 0) {
-                       if (errno != EPIPE) 
+                       fprintf(stderr, "local: %s: %s\n", local,
+                               strerror(errno));
+               if (d <= 0) {
+                       if (d == 0)
+                               fprintf(stderr, "netout: write returned 0?\n");
+                       else if (errno != EPIPE) 
                                perror("netout");
                        bytes = -1;
                }
                                perror("netout");
                        bytes = -1;
                }
@@ -568,7 +589,8 @@ sendrequest(cmd, local, remote)
                        (void) fflush(stdout);
                }
                if (ferror(fin))
                        (void) fflush(stdout);
                }
                if (ferror(fin))
-                       perror(local);
+                       fprintf(stderr, "local: %s: %s\n", local,
+                               strerror(errno));
                if (ferror(dout)) {
                        if (errno != EPIPE)
                                perror("netout");
                if (ferror(dout)) {
                        if (errno != EPIPE)
                                perror("netout");
@@ -585,7 +607,7 @@ sendrequest(cmd, local, remote)
        if (oldintp)
                (void) signal(SIGPIPE, oldintp);
        if (bytes > 0)
        if (oldintp)
                (void) signal(SIGPIPE, oldintp);
        if (bytes > 0)
-               ptransfer("sent", bytes, &start, &stop, local, remote);
+               ptransfer("sent", bytes, &start, &stop);
        return;
 abort:
        (void) gettimeofday(&stop, (struct timezone *)0);
        return;
 abort:
        (void) gettimeofday(&stop, (struct timezone *)0);
@@ -607,37 +629,43 @@ abort:
        if (closefunc != NULL && fin != NULL)
                (*closefunc)(fin);
        if (bytes > 0)
        if (closefunc != NULL && fin != NULL)
                (*closefunc)(fin);
        if (bytes > 0)
-               ptransfer("sent", bytes, &start, &stop, local, remote);
+               ptransfer("sent", bytes, &start, &stop);
 }
 
 jmp_buf        recvabort;
 
 }
 
 jmp_buf        recvabort;
 
+sig_t
 abortrecv()
 {
 
        mflag = 0;
        abrtflag = 0;
 abortrecv()
 {
 
        mflag = 0;
        abrtflag = 0;
-       printf("\n");
+       printf("\nreceive aborted\nwaiting for remote to finish abort\n");
        (void) fflush(stdout);
        longjmp(recvabort, 1);
 }
 
        (void) fflush(stdout);
        longjmp(recvabort, 1);
 }
 
-recvrequest(cmd, local, remote, mode)
+recvrequest(cmd, local, remote, mode, printnames)
        char *cmd, *local, *remote, *mode;
 {
        FILE *fout, *din = 0, *popen();
        char *cmd, *local, *remote, *mode;
 {
        FILE *fout, *din = 0, *popen();
-       int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)(); 
-       int abortrecv(), oldverbose, oldtype = 0, is_retr, tcrflag, nfnd;
-       char *buf, *gunique(), msg;
+       char *bufp, *gunique(), msg;
+       static char *buf;
        static int bufsize;
        static int bufsize;
+       static char *buf;
        long bytes = 0, hashbytes = HASHBYTES;
        long bytes = 0, hashbytes = HASHBYTES;
-       struct fd_set mask;
        register int c, d;
        struct timeval start, stop;
        struct stat st;
        extern char *malloc();
 
        is_retr = strcmp(cmd, "RETR") == 0;
        register int c, d;
        struct timeval start, stop;
        struct stat st;
        extern char *malloc();
 
        is_retr = strcmp(cmd, "RETR") == 0;
+       if (is_retr && verbose && printnames) {
+               if (local && *local != '-')
+                       printf("local: %s ", local);
+               if (remote)
+                       printf("remote: %s\n", remote);
+       }
        if (proxy && is_retr) {
                proxtrans(cmd, local, remote);
                return;
        if (proxy && is_retr) {
                proxtrans(cmd, local, remote);
                return;
@@ -665,7 +693,8 @@ recvrequest(cmd, local, remote, mode)
                        char *dir = rindex(local, '/');
 
                        if (errno != ENOENT && errno != EACCES) {
                        char *dir = rindex(local, '/');
 
                        if (errno != ENOENT && errno != EACCES) {
-                               perror(local);
+                               fprintf(stderr, "local: %s: %s\n", local,
+                                       strerror(errno));
                                (void) signal(SIGINT, oldintr);
                                code = -1;
                                return;
                                (void) signal(SIGINT, oldintr);
                                code = -1;
                                return;
@@ -676,14 +705,17 @@ recvrequest(cmd, local, remote, mode)
                        if (dir != NULL)
                                *dir = '/';
                        if (d < 0) {
                        if (dir != NULL)
                                *dir = '/';
                        if (d < 0) {
-                               perror(local);
+                               fprintf(stderr, "local: %s: %s\n", local,
+                                       strerror(errno));
                                (void) signal(SIGINT, oldintr);
                                code = -1;
                                return;
                        }
                        if (!runique && errno == EACCES &&
                            chmod(local, 0600) < 0) {
                                (void) signal(SIGINT, oldintr);
                                code = -1;
                                return;
                        }
                        if (!runique && errno == EACCES &&
                            chmod(local, 0600) < 0) {
-                               perror(local);
+                               fprintf(stderr, "local: %s: %s\n", local,
+                                       strerror(errno));
+                               (void) signal(SIGINT, oldintr);
                                (void) signal(SIGINT, oldintr);
                                code = -1;
                                return;
                                (void) signal(SIGINT, oldintr);
                                code = -1;
                                return;
@@ -701,6 +733,11 @@ recvrequest(cmd, local, remote, mode)
                        return;
                }
        }
                        return;
                }
        }
+       if (!is_retr) {
+               if (curtype != TYPE_A)
+                       changetype(TYPE_A, 0);
+       } else if (curtype != type)
+               changetype(type, 0);
        if (initconn()) {
                (void) signal(SIGINT, oldintr);
                code = -1;
        if (initconn()) {
                (void) signal(SIGINT, oldintr);
                code = -1;
@@ -708,59 +745,17 @@ recvrequest(cmd, local, remote, mode)
        }
        if (setjmp(recvabort))
                goto abort;
        }
        if (setjmp(recvabort))
                goto abort;
-       if (!is_retr) {
-               if (type != TYPE_A) {
-                       oldtype = type;
-                       oldverbose = verbose;
-                       if (!debug)
-                               verbose = 0;
-                       setascii();
-                       verbose = oldverbose;
-               }
-       } else if (restart_point) {
-               if (command("REST %ld", (long) restart_point) != CONTINUE)
-                       return;
-       }
+       if (is_retr && restart_point &&
+           command("REST %ld", (long) restart_point) != CONTINUE)
+               return;
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
-                       if (oldtype) {
-                               if (!debug)
-                                       verbose = 0;
-                               switch (oldtype) {
-                                       case TYPE_I:
-                                               setbinary();
-                                               break;
-                                       case TYPE_E:
-                                               setebcdic();
-                                               break;
-                                       case TYPE_L:
-                                               settenex();
-                                               break;
-                                       }
-                               verbose = oldverbose;
-                       }
                        return;
                }
        } else {
                if (command("%s", cmd) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
                        return;
                }
        } else {
                if (command("%s", cmd) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
-                       if (oldtype) {
-                               if (!debug)
-                                       verbose = 0;
-                               switch (oldtype) {
-                                       case TYPE_I:
-                                               setbinary();
-                                               break;
-                                       case TYPE_E:
-                                               setebcdic();
-                                               break;
-                                       case TYPE_L:
-                                               settenex();
-                                               break;
-                                       }
-                               verbose = oldverbose;
-                       }
                        return;
                }
        }
                        return;
                }
        }
@@ -780,7 +775,8 @@ recvrequest(cmd, local, remote, mode)
        } else {
                fout = fopen(local, mode);
                if (fout == NULL) {
        } else {
                fout = fopen(local, mode);
                if (fout == NULL) {
-                       perror(local);
+                       fprintf(stderr, "local: %s: %s\n", local,
+                               strerror(errno));
                        goto abort;
                }
                closefunc = fclose;
                        goto abort;
                }
                closefunc = fclose;
@@ -790,25 +786,20 @@ recvrequest(cmd, local, remote, mode)
        if (st.st_blksize > bufsize) {
                if (buf)
                        (void) free(buf);
        if (st.st_blksize > bufsize) {
                if (buf)
                        (void) free(buf);
-               buf = malloc(st.st_blksize);
+               buf = malloc((unsigned)st.st_blksize);
                if (buf == NULL) {
                        perror("malloc");
                if (buf == NULL) {
                        perror("malloc");
+                       bufsize = 0;
+                       bufsize = 0;
                        goto abort;
                }
                bufsize = st.st_blksize;
        }
        (void) gettimeofday(&start, (struct timezone *)0);
                        goto abort;
                }
                bufsize = st.st_blksize;
        }
        (void) gettimeofday(&start, (struct timezone *)0);
-       switch (type) {
+       switch (curtype) {
 
        case TYPE_I:
        case TYPE_L:
 
        case TYPE_I:
        case TYPE_L:
-               if (restart_point &&
-                   lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
-                       perror(local);
-                       if (closefunc != NULL)
-                               (*closefunc)(fout);
-                       return;
-               }
                errno = d = 0;
                while ((c = read(fileno(din), buf, bufsize)) > 0) {
                        if ((d = write(fileno(fout), buf, c)) != c)
                errno = d = 0;
                while ((c = read(fileno(din), buf, bufsize)) > 0) {
                        if ((d = write(fileno(fout), buf, c)) != c)
@@ -833,33 +824,18 @@ recvrequest(cmd, local, remote, mode)
                                perror("netin");
                        bytes = -1;
                }
                                perror("netin");
                        bytes = -1;
                }
-               if (d < 0)
-                       perror(local);
+               if (d < c) {
+                       if (d < 0)
+                               perror(local);
+                       else
+                               fprintf(stderr, "%s: short write\n", local);
+               }
                break;
 
        case TYPE_A:
                break;
 
        case TYPE_A:
-               if (restart_point) {
-                       register int i, n, c;
-
-                       if (fseek(fout, 0L, L_SET) < 0)
-                               goto done;
-                       n = restart_point;
-                       i = 0;
-                       while (i++ < n) {
-                               if ((c=getc(fout)) == EOF)
-                                       goto done;
-                               if (c == '\n')
-                                       i++;
-                       }       
-                       if (fseek(fout, 0L, L_INCR) < 0) {
-done:
-                               perror(local);
-                               if (closefunc != NULL)
-                                       (*closefunc)(fout);
-                               return;
-                       }
-               }
                while ((c = getc(din)) != EOF) {
                while ((c = getc(din)) != EOF) {
+                       if (c == '\n')
+                               bare_lfs++;
                        while (c == '\r') {
                                while (hash && (bytes >= hashbytes)) {
                                        (void) putchar('#');
                        while (c == '\r') {
                                while (hash && (bytes >= hashbytes)) {
                                        (void) putchar('#');
@@ -871,7 +847,14 @@ done:
                                        if (ferror(fout))
                                                goto break2;
                                        (void) putc('\r', fout);
                                        if (ferror(fout))
                                                goto break2;
                                        (void) putc('\r', fout);
-                                       if (c == '\0' || c == EOF)
+                                       if (c == '\0') {
+                                               bytes++;
+                                               goto contin2;
+                                       }
+                                       if (c == EOF)
+                                               goto contin2;
+                                       }
+                                       if (c == EOF)
                                                goto contin2;
                                }
                        }
                                                goto contin2;
                                }
                        }
@@ -880,19 +863,24 @@ done:
        contin2:        ;
                }
 break2:
        contin2:        ;
                }
 break2:
+               if (bare_lfs) {
+                       printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
+                       printf("File may not have transferred correctly.\n");
+               }
                if (hash) {
                        if (bytes < hashbytes)
                                (void) putchar('#');
                        (void) putchar('\n');
                        (void) fflush(stdout);
                }
                if (hash) {
                        if (bytes < hashbytes)
                                (void) putchar('#');
                        (void) putchar('\n');
                        (void) fflush(stdout);
                }
-               if (ferror(din)){
+               if (ferror(din)) {
                        if (errno != EPIPE)
                        if (errno != EPIPE)
-                               perror ("netin");
+                               perror("netin");
                        bytes = -1;
                }
                if (ferror(fout))
                        bytes = -1;
                }
                if (ferror(fout))
-                       perror (local);
+                       fprintf(stderr, "local: %s: %s\n", local,
+                               strerror(errno));
                break;
        }
        if (closefunc != NULL)
                break;
        }
        if (closefunc != NULL)
@@ -904,23 +892,7 @@ break2:
        (void) fclose(din);
        (void) getreply(0);
        if (bytes > 0 && is_retr)
        (void) fclose(din);
        (void) getreply(0);
        if (bytes > 0 && is_retr)
-               ptransfer("received", bytes, &start, &stop, local, remote);
-       if (oldtype) {
-               if (!debug)
-                       verbose = 0;
-               switch (oldtype) {
-                       case TYPE_I:
-                               setbinary();
-                               break;
-                       case TYPE_E:
-                               setebcdic();
-                               break;
-                       case TYPE_L:
-                               settenex();
-                               break;
-               }
-               verbose = oldverbose;
-       }
+               ptransfer("received", bytes, &start, &stop);
        return;
 abort:
 
        return;
 abort:
 
@@ -929,63 +901,14 @@ abort:
        (void) gettimeofday(&stop, (struct timezone *)0);
        if (oldintp)
                (void) signal(SIGPIPE, oldintr);
        (void) gettimeofday(&stop, (struct timezone *)0);
        if (oldintp)
                (void) signal(SIGPIPE, oldintr);
-       (void) signal(SIGINT,SIG_IGN);
-       if (oldtype) {
-               if (!debug)
-                       verbose = 0;
-               switch (oldtype) {
-                       case TYPE_I:
-                               setbinary();
-                               break;
-                       case TYPE_E:
-                               setebcdic();
-                               break;
-                       case TYPE_L:
-                               settenex();
-                               break;
-               }
-               verbose = oldverbose;
-       }
+       (void) signal(SIGINT, SIG_IGN);
        if (!cpend) {
                code = -1;
        if (!cpend) {
                code = -1;
-               (void) signal(SIGINT,oldintr);
+               (void) signal(SIGINT, oldintr);
                return;
        }
 
                return;
        }
 
-       fprintf(cout,"%c%c",IAC,IP);
-       (void) fflush(cout); 
-       msg = IAC;
-/* send IAC in urgent mode instead of DM because UNIX places oob mark */
-/* after urgent byte rather than before as now is protocol            */
-       if (send(fileno(cout),&msg,1,MSG_OOB) != 1) {
-               perror("abort");
-       }
-       fprintf(cout,"%cABOR\r\n",DM);
-       (void) fflush(cout);
-       FD_ZERO(&mask);
-       FD_SET(fileno(cin), &mask);
-       if (din) { 
-               FD_SET(fileno(din), &mask);
-       }
-       if ((nfnd = empty(&mask,10)) <= 0) {
-               if (nfnd < 0) {
-                       perror("abort");
-               }
-               code = -1;
-               lostpeer();
-       }
-       if (din && FD_ISSET(fileno(din), &mask)) {
-               while ((c = read(fileno(din), buf, bufsize)) > 0)
-                       ;
-       }
-       if ((c = getreply(0)) == ERROR && code == 552) { /* needed for nic style abort */
-               if (data >= 0) {
-                       (void) close(data);
-                       data = -1;
-               }
-               (void) getreply(0);
-       }
-       (void) getreply(0);
+       abort_remote(din);
        code = -1;
        if (data >= 0) {
                (void) close(data);
        code = -1;
        if (data >= 0) {
                (void) close(data);
@@ -996,8 +919,8 @@ abort:
        if (din)
                (void) fclose(din);
        if (bytes > 0)
        if (din)
                (void) fclose(din);
        if (bytes > 0)
-               ptransfer("received", bytes, &start, &stop, local, remote);
-       (void) signal(SIGINT,oldintr);
+               ptransfer("received", bytes, &start, &stop);
+       (void) signal(SIGINT, oldintr);
 }
 
 /*
 }
 
 /*
@@ -1005,7 +928,7 @@ abort:
  * before we send the command, otherwise the
  * server's connect may fail.
  */
  * before we send the command, otherwise the
  * server's connect may fail.
  */
-int sendport = -1;
+int sendport;
 
 initconn()
 {
 
 initconn()
 {
@@ -1018,7 +941,7 @@ noport:
        if (sendport)
                data_addr.sin_port = 0; /* let system pick one */ 
        if (data != -1)
        if (sendport)
                data_addr.sin_port = 0; /* let system pick one */ 
        if (data != -1)
-               (void) close (data);
+               (void) close(data);
        data = socket(AF_INET, SOCK_STREAM, 0);
        if (data < 0) {
                perror("ftp: socket");
        data = socket(AF_INET, SOCK_STREAM, 0);
        if (data < 0) {
                perror("ftp: socket");
@@ -1039,7 +962,7 @@ noport:
            setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
                perror("ftp: setsockopt (ignored)");
        len = sizeof (data_addr);
            setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
                perror("ftp: setsockopt (ignored)");
        len = sizeof (data_addr);
-       if (getsockname(data, (char *)&data_addr, &len) < 0) {
+       if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
                perror("ftp: getsockname");
                goto bad;
        }
                perror("ftp: getsockname");
                goto bad;
        }
@@ -1088,8 +1011,8 @@ dataconn(mode)
        return (fdopen(data, mode));
 }
 
        return (fdopen(data, mode));
 }
 
-ptransfer(direction, bytes, t0, t1, local, remote)
-       char *direction, *local, *remote;
+ptransfer(direction, bytes, t0, t1)
+       char *direction;
        long bytes;
        struct timeval *t0, *t1;
 {
        long bytes;
        struct timeval *t0, *t1;
 {
@@ -1103,11 +1026,6 @@ ptransfer(direction, bytes, t0, t1, local, remote)
                bs = bytes / nz(s);
                printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
                    bytes, direction, s, bs / 1024.);
                bs = bytes / nz(s);
                printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
                    bytes, direction, s, bs / 1024.);
-       } else {
-               if (local && *local != '-')
-                       printf("local: %s ", local);
-               if (remote)
-                       printf("remote: %s\n", remote);
        }
 }
 
        }
 }
 
@@ -1131,6 +1049,7 @@ tvsub(tdiff, t1, t0)
                tdiff->tv_sec--, tdiff->tv_usec += 1000000;
 }
 
                tdiff->tv_sec--, tdiff->tv_usec += 1000000;
 }
 
+sig_t
 psabort()
 {
        extern int abrtflag;
 psabort()
 {
        extern int abrtflag;
@@ -1142,7 +1061,7 @@ pswitch(flag)
        int flag;
 {
        extern int proxy, abrtflag;
        int flag;
 {
        extern int proxy, abrtflag;
-       int (*oldintr)();
+       sig_t (*oldintr)();
        static struct comvars {
                int connect;
                char name[MAXHOSTNAMELEN];
        static struct comvars {
                int connect;
                char name[MAXHOSTNAMELEN];
@@ -1151,6 +1070,7 @@ pswitch(flag)
                FILE *in;
                FILE *out;
                int tpe;
                FILE *in;
                FILE *out;
                int tpe;
+               int curtpe;
                int cpnd;
                int sunqe;
                int runqe;
                int cpnd;
                int sunqe;
                int runqe;
@@ -1161,7 +1081,7 @@ pswitch(flag)
                int mapflg;
                char mi[MAXPATHLEN];
                char mo[MAXPATHLEN];
                int mapflg;
                char mi[MAXPATHLEN];
                char mo[MAXPATHLEN];
-               } proxstruct, tmpstruct;
+       } proxstruct, tmpstruct;
        struct comvars *ip, *op;
 
        abrtflag = 0;
        struct comvars *ip, *op;
 
        abrtflag = 0;
@@ -1172,8 +1092,7 @@ pswitch(flag)
                ip = &tmpstruct;
                op = &proxstruct;
                proxy++;
                ip = &tmpstruct;
                op = &proxstruct;
                proxy++;
-       }
-       else {
+       } else {
                if (!proxy)
                        return;
                ip = &proxstruct;
                if (!proxy)
                        return;
                ip = &proxstruct;
@@ -1198,8 +1117,8 @@ pswitch(flag)
        cout = op->out;
        ip->tpe = type;
        type = op->tpe;
        cout = op->out;
        ip->tpe = type;
        type = op->tpe;
-       if (!type)
-               type = 1;
+       ip->curtpe = curtype;
+       curtype = op->curtpe;
        ip->cpnd = cpend;
        cpend = op->cpnd;
        ip->sunqe = sunique;
        ip->cpnd = cpend;
        cpend = op->cpnd;
        ip->sunqe = sunique;
@@ -1234,6 +1153,7 @@ pswitch(flag)
 jmp_buf ptabort;
 int ptabflg;
 
 jmp_buf ptabort;
 int ptabflg;
 
+sig_t
 abortpt()
 {
        printf("\n");
 abortpt()
 {
        printf("\n");
@@ -1247,7 +1167,8 @@ abortpt()
 proxtrans(cmd, local, remote)
        char *cmd, *local, *remote;
 {
 proxtrans(cmd, local, remote)
        char *cmd, *local, *remote;
 {
-       int (*oldintr)(), abortpt(), tmptype, oldtype = 0, secndflag = 0, nfnd;
+       sig_t (*oldintr)(), abortpt();
+       int secndflag = 0, prox_type, nfnd;
        extern jmp_buf ptabort;
        char *cmd2;
        struct fd_set mask;
        extern jmp_buf ptabort;
        char *cmd2;
        struct fd_set mask;
@@ -1256,11 +1177,18 @@ proxtrans(cmd, local, remote)
                cmd2 = "RETR";
        else
                cmd2 = runique ? "STOU" : "STOR";
                cmd2 = "RETR";
        else
                cmd2 = runique ? "STOU" : "STOR";
+       if ((prox_type = type) == 0) {
+               if (unix_server && unix_proxy)
+                       prox_type = TYPE_I;
+               else
+                       prox_type = TYPE_A;
+       }
+       if (curtype != prox_type)
+               changetype(prox_type, 1);
        if (command("PASV") != COMPLETE) {
        if (command("PASV") != COMPLETE) {
-               printf("proxy server does not support third part transfers.\n");
+               printf("proxy server does not support third party transfers.\n");
                return;
        }
                return;
        }
-       tmptype = type;
        pswitch(0);
        if (!connected) {
                printf("No primary connection\n");
        pswitch(0);
        if (!connected) {
                printf("No primary connection\n");
@@ -1268,40 +1196,9 @@ proxtrans(cmd, local, remote)
                code = -1;
                return;
        }
                code = -1;
                return;
        }
-       if (type != tmptype) {
-               oldtype = type;
-               switch (tmptype) {
-                       case TYPE_A:
-                               setascii();
-                               break;
-                       case TYPE_I:
-                               setbinary();
-                               break;
-                       case TYPE_E:
-                               setebcdic();
-                               break;
-                       case TYPE_L:
-                               settenex();
-                               break;
-               }
-       }
+       if (curtype != prox_type)
+               changetype(prox_type, 1);
        if (command("PORT %s", pasv) != COMPLETE) {
        if (command("PORT %s", pasv) != COMPLETE) {
-               switch (oldtype) {
-                       case 0:
-                               break;
-                       case TYPE_A:
-                               setascii();
-                               break;
-                       case TYPE_I:
-                               setbinary();
-                               break;
-                       case TYPE_E:
-                               setebcdic();
-                               break;
-                       case TYPE_L:
-                               settenex();
-                               break;
-               }
                pswitch(1);
                return;
        }
                pswitch(1);
                return;
        }
@@ -1310,22 +1207,6 @@ proxtrans(cmd, local, remote)
        oldintr = signal(SIGINT, abortpt);
        if (command("%s %s", cmd, remote) != PRELIM) {
                (void) signal(SIGINT, oldintr);
        oldintr = signal(SIGINT, abortpt);
        if (command("%s %s", cmd, remote) != PRELIM) {
                (void) signal(SIGINT, oldintr);
-               switch (oldtype) {
-                       case 0:
-                               break;
-                       case TYPE_A:
-                               setascii();
-                               break;
-                       case TYPE_I:
-                               setbinary();
-                               break;
-                       case TYPE_E:
-                               setebcdic();
-                               break;
-                       case TYPE_L:
-                               settenex();
-                               break;
-               }
                pswitch(1);
                return;
        }
                pswitch(1);
                return;
        }
@@ -1339,22 +1220,6 @@ proxtrans(cmd, local, remote)
        pswitch(0);
        (void) getreply(0);
        (void) signal(SIGINT, oldintr);
        pswitch(0);
        (void) getreply(0);
        (void) signal(SIGINT, oldintr);
-       switch (oldtype) {
-               case 0:
-                       break;
-               case TYPE_A:
-                       setascii();
-                       break;
-               case TYPE_I:
-                       setbinary();
-                       break;
-               case TYPE_E:
-                       setebcdic();
-                       break;
-               case TYPE_L:
-                       settenex();
-                       break;
-       }
        pswitch(1);
        ptflag = 0;
        printf("local: %s remote: %s\n", local, remote);
        pswitch(1);
        ptflag = 0;
        printf("local: %s remote: %s\n", local, remote);
@@ -1369,46 +1234,8 @@ abort:
        if (!cpend && !secndflag) {  /* only here if cmd = "STOR" (proxy=1) */
                if (command("%s %s", cmd2, local) != PRELIM) {
                        pswitch(0);
        if (!cpend && !secndflag) {  /* only here if cmd = "STOR" (proxy=1) */
                if (command("%s %s", cmd2, local) != PRELIM) {
                        pswitch(0);
-                       switch (oldtype) {
-                               case 0:
-                                       break;
-                               case TYPE_A:
-                                       setascii();
-                                       break;
-                               case TYPE_I:
-                                       setbinary();
-                                       break;
-                               case TYPE_E:
-                                       setebcdic();
-                                       break;
-                               case TYPE_L:
-                                       settenex();
-                                       break;
-                       }
-                       if (cpend) {
-                               char msg[2];
-
-                               fprintf(cout,"%c%c",IAC,IP);
-                               (void) fflush(cout); 
-                               *msg = IAC;
-                               *(msg+1) = DM;
-                               if (send(fileno(cout),msg,2,MSG_OOB) != 2)
-                                       perror("abort");
-                               fprintf(cout,"ABOR\r\n");
-                               (void) fflush(cout);
-                               FD_ZERO(&mask);
-                               FD_SET(fileno(cin), &mask);
-                               if ((nfnd = empty(&mask,10)) <= 0) {
-                                       if (nfnd < 0) {
-                                               perror("abort");
-                                       }
-                                       if (ptabflg)
-                                               code = -1;
-                                       lostpeer();
-                               }
-                               (void) getreply(0);
-                               (void) getreply(0);
-                       }
+                       if (cpend)
+                               abort_remote((FILE *) NULL);
                }
                pswitch(1);
                if (ptabflg)
                }
                pswitch(1);
                if (ptabflg)
@@ -1416,74 +1243,14 @@ abort:
                (void) signal(SIGINT, oldintr);
                return;
        }
                (void) signal(SIGINT, oldintr);
                return;
        }
-       if (cpend) {
-               char msg[2];
-
-               fprintf(cout,"%c%c",IAC,IP);
-               (void) fflush(cout); 
-               *msg = IAC;
-               *(msg+1) = DM;
-               if (send(fileno(cout),msg,2,MSG_OOB) != 2)
-                       perror("abort");
-               fprintf(cout,"ABOR\r\n");
-               (void) fflush(cout);
-               FD_ZERO(&mask);
-               FD_SET(fileno(cin), &mask);
-               if ((nfnd = empty(&mask,10)) <= 0) {
-                       if (nfnd < 0) {
-                               perror("abort");
-                       }
-                       if (ptabflg)
-                               code = -1;
-                       lostpeer();
-               }
-               (void) getreply(0);
-               (void) getreply(0);
-       }
+       if (cpend)
+               abort_remote((FILE *) NULL);
        pswitch(!proxy);
        if (!cpend && !secndflag) {  /* only if cmd = "RETR" (proxy=1) */
                if (command("%s %s", cmd2, local) != PRELIM) {
                        pswitch(0);
        pswitch(!proxy);
        if (!cpend && !secndflag) {  /* only if cmd = "RETR" (proxy=1) */
                if (command("%s %s", cmd2, local) != PRELIM) {
                        pswitch(0);
-                       switch (oldtype) {
-                               case 0:
-                                       break;
-                               case TYPE_A:
-                                       setascii();
-                                       break;
-                               case TYPE_I:
-                                       setbinary();
-                                       break;
-                               case TYPE_E:
-                                       setebcdic();
-                                       break;
-                               case TYPE_L:
-                                       settenex();
-                                       break;
-                       }
-                       if (cpend) {
-                               char msg[2];
-
-                               fprintf(cout,"%c%c",IAC,IP);
-                               (void) fflush(cout); 
-                               *msg = IAC;
-                               *(msg+1) = DM;
-                               if (send(fileno(cout),msg,2,MSG_OOB) != 2)
-                                       perror("abort");
-                               fprintf(cout,"ABOR\r\n");
-                               (void) fflush(cout);
-                               FD_ZERO(&mask);
-                               FD_SET(fileno(cin), &mask);
-                               if ((nfnd = empty(&mask,10)) <= 0) {
-                                       if (nfnd < 0) {
-                                               perror("abort");
-                                       }
-                                       if (ptabflg)
-                                               code = -1;
-                                       lostpeer();
-                               }
-                               (void) getreply(0);
-                               (void) getreply(0);
-                       }
+                       if (cpend)
+                               abort_remote((FILE *) NULL);
                        pswitch(1);
                        if (ptabflg)
                                code = -1;
                        pswitch(1);
                        if (ptabflg)
                                code = -1;
@@ -1491,35 +1258,13 @@ abort:
                        return;
                }
        }
                        return;
                }
        }
-       if (cpend) {
-               char msg[2];
-
-               fprintf(cout,"%c%c",IAC,IP);
-               (void) fflush(cout); 
-               *msg = IAC;
-               *(msg+1) = DM;
-               if (send(fileno(cout),msg,2,MSG_OOB) != 2)
-                       perror("abort");
-               fprintf(cout,"ABOR\r\n");
-               (void) fflush(cout);
-               FD_ZERO(&mask);
-               FD_SET(fileno(cin), &mask);
-               if ((nfnd = empty(&mask,10)) <= 0) {
-                       if (nfnd < 0) {
-                               perror("abort");
-                       }
-                       if (ptabflg)
-                               code = -1;
-                       lostpeer();
-               }
-               (void) getreply(0);
-               (void) getreply(0);
-       }
+       if (cpend)
+               abort_remote((FILE *) NULL);
        pswitch(!proxy);
        if (cpend) {
                FD_ZERO(&mask);
                FD_SET(fileno(cin), &mask);
        pswitch(!proxy);
        if (cpend) {
                FD_ZERO(&mask);
                FD_SET(fileno(cin), &mask);
-               if ((nfnd = empty(&mask,10)) <= 0) {
+               if ((nfnd = empty(&mask, 10)) <= 0) {
                        if (nfnd < 0) {
                                perror("abort");
                        }
                        if (nfnd < 0) {
                                perror("abort");
                        }
@@ -1532,22 +1277,6 @@ abort:
        }
        if (proxy)
                pswitch(0);
        }
        if (proxy)
                pswitch(0);
-       switch (oldtype) {
-               case 0:
-                       break;
-               case TYPE_A:
-                       setascii();
-                       break;
-               case TYPE_I:
-                       setbinary();
-                       break;
-               case TYPE_E:
-                       setebcdic();
-                       break;
-               case TYPE_L:
-                       settenex();
-                       break;
-       }
        pswitch(1);
        if (ptabflg)
                code = -1;
        pswitch(1);
        if (ptabflg)
                code = -1;
@@ -1588,7 +1317,7 @@ gunique(local)
        if (cp)
                *cp = '/';
        if (d < 0) {
        if (cp)
                *cp = '/';
        if (d < 0) {
-               perror(local);
+               fprintf(stderr, "local: %s: %s\n", local, strerror(errno));
                return((char *) 0);
        }
        (void) strcpy(new, local);
                return((char *) 0);
        }
        (void) strcpy(new, local);
@@ -1618,3 +1347,43 @@ gunique(local)
        }
        return(new);
 }
        }
        return(new);
 }
+
+abort_remote(din)
+FILE *din;
+{
+       char buf[BUFSIZ];
+       int nfnd;
+       struct fd_set mask;
+
+       /*
+        * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
+        * after urgent byte rather than before as is protocol now
+        */
+       sprintf(buf, "%c%c%c", IAC, IP, IAC);
+       if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
+               perror("abort");
+       fprintf(cout,"%cABOR\r\n", DM);
+       (void) fflush(cout);
+       FD_ZERO(&mask);
+       FD_SET(fileno(cin), &mask);
+       if (din) { 
+               FD_SET(fileno(din), &mask);
+       }
+       if ((nfnd = empty(&mask, 10)) <= 0) {
+               if (nfnd < 0) {
+                       perror("abort");
+               }
+               if (ptabflg)
+                       code = -1;
+               lostpeer();
+       }
+       if (din && FD_ISSET(fileno(din), &mask)) {
+               while (read(fileno(din), buf, BUFSIZ) > 0)
+                       /* LOOP */;
+       }
+       if (getreply(0) == ERROR && code == 552) {
+               /* 552 needed for nic style abort */
+               (void) getreply(0);
+       }
+       (void) getreply(0);
+}