add typedef for signal return for better portability
[unix-history] / usr / src / usr.bin / ftp / ftp.c
index 5c47733..9f76af4 100644 (file)
@@ -1,19 +1,30 @@
 /*
 /*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1985, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ftp.c      5.8 (Berkeley) %G%";
-#endif not lint
-
-#include "ftp_var.h"
+static char sccsid[] = "@(#)ftp.c      5.29 (Berkeley) %G%";
+#endif /* not lint */
 
 
+#include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/time.h>
+#include <sys/file.h>
 
 #include <netinet/in.h>
 #include <arpa/ftp.h>
 
 #include <netinet/in.h>
 #include <arpa/ftp.h>
@@ -26,14 +37,16 @@ static char sccsid[] = "@(#)ftp.c   5.8 (Berkeley) %G%";
 #include <fcntl.h>
 #include <pwd.h>
 
 #include <fcntl.h>
 #include <pwd.h>
 
+#include "ftp_var.h"
+
 struct sockaddr_in hisctladdr;
 struct sockaddr_in data_addr;
 int    data = -1;
 struct sockaddr_in hisctladdr;
 struct sockaddr_in data_addr;
 int    data = -1;
-int     telflag = 0;
 int    abrtflag = 0;
 int    ptflag = 0;
 int    connected;
 struct sockaddr_in myctladdr;
 int    abrtflag = 0;
 int    ptflag = 0;
 int    connected;
 struct sockaddr_in myctladdr;
+uid_t  getuid();
 
 FILE   *cin, *cout;
 FILE   *dataconn();
 
 FILE   *cin, *cout;
 FILE   *dataconn();
@@ -44,27 +57,26 @@ hookup(host, port)
        int port;
 {
        register struct hostent *hp = 0;
        int port;
 {
        register struct hostent *hp = 0;
-       int s,len,oldverbose;
+       int s,len;
        static char hostnamebuf[80];
        static char hostnamebuf[80];
-       char msg[2];
 
        bzero((char *)&hisctladdr, sizeof (hisctladdr));
        hisctladdr.sin_addr.s_addr = inet_addr(host);
        if (hisctladdr.sin_addr.s_addr != -1) {
                hisctladdr.sin_family = AF_INET;
 
        bzero((char *)&hisctladdr, sizeof (hisctladdr));
        hisctladdr.sin_addr.s_addr = inet_addr(host);
        if (hisctladdr.sin_addr.s_addr != -1) {
                hisctladdr.sin_family = AF_INET;
-               (void) strcpy(hostnamebuf, host);
-       }
-       else {
+               (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));
+       } else {
                hp = gethostbyname(host);
                if (hp == NULL) {
                hp = gethostbyname(host);
                if (hp == NULL) {
-                       printf("%s: unknown host\n", host);
+                       fprintf(stderr, "ftp: %s: ", host);
+                       herror((char *)NULL);
                        code = -1;
                        return((char *) 0);
                }
                hisctladdr.sin_family = hp->h_addrtype;
                bcopy(hp->h_addr_list[0],
                    (caddr_t)&hisctladdr.sin_addr, hp->h_length);
                        code = -1;
                        return((char *) 0);
                }
                hisctladdr.sin_family = hp->h_addrtype;
                bcopy(hp->h_addr_list[0],
                    (caddr_t)&hisctladdr.sin_addr, hp->h_length);
-               (void) strcpy(hostnamebuf, hp->h_name);
+               (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
        }
        hostname = hostnamebuf;
        s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
        }
        hostname = hostnamebuf;
        s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
@@ -74,19 +86,26 @@ hookup(host, port)
                return (0);
        }
        hisctladdr.sin_port = port;
                return (0);
        }
        hisctladdr.sin_port = port;
-       while (connect(s, (caddr_t)&hisctladdr, sizeof (hisctladdr)) < 0) {
+       while (connect(s, &hisctladdr, sizeof (hisctladdr)) < 0) {
                if (hp && hp->h_addr_list[1]) {
                        int oerrno = errno;
 
                        fprintf(stderr, "ftp: connect to address %s: ",
                                inet_ntoa(hisctladdr.sin_addr));
                        errno = oerrno;
                if (hp && hp->h_addr_list[1]) {
                        int oerrno = errno;
 
                        fprintf(stderr, "ftp: connect to address %s: ",
                                inet_ntoa(hisctladdr.sin_addr));
                        errno = oerrno;
-                       perror(0);
+                       perror((char *) 0);
                        hp->h_addr_list++;
                        bcopy(hp->h_addr_list[0],
                             (caddr_t)&hisctladdr.sin_addr, hp->h_length);
                        hp->h_addr_list++;
                        bcopy(hp->h_addr_list[0],
                             (caddr_t)&hisctladdr.sin_addr, hp->h_length);
-                       fprintf(stderr, "Trying %s...\n",
+                       fprintf(stdout, "Trying %s...\n",
                                inet_ntoa(hisctladdr.sin_addr));
                                inet_ntoa(hisctladdr.sin_addr));
+                       (void) close(s);
+                       s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
+                       if (s < 0) {
+                               perror("ftp: socket");
+                               code = -1;
+                               return (0);
+                       }
                        continue;
                }
                perror("ftp: connect");
                        continue;
                }
                perror("ftp: connect");
@@ -104,42 +123,36 @@ hookup(host, port)
        if (cin == NULL || cout == NULL) {
                fprintf(stderr, "ftp: fdopen failed.\n");
                if (cin)
        if (cin == NULL || cout == NULL) {
                fprintf(stderr, "ftp: fdopen failed.\n");
                if (cin)
-                       fclose(cin);
+                       (void) fclose(cin);
                if (cout)
                if (cout)
-                       fclose(cout);
+                       (void) fclose(cout);
                code = -1;
                goto bad;
        }
        if (verbose)
                printf("Connected to %s.\n", hostname);
                code = -1;
                goto bad;
        }
        if (verbose)
                printf("Connected to %s.\n", hostname);
-       if (getreply(0) != 2) {         /* read startup message from server */
+       if (getreply(0) > 2) {  /* read startup message from server */
                if (cin)
                if (cin)
-                       fclose(cin);
+                       (void) fclose(cin);
                if (cout)
                if (cout)
-                       fclose(cout);
+                       (void) fclose(cout);
                code = -1;
                goto bad;
        }
                code = -1;
                goto bad;
        }
+#ifdef SO_OOBINLINE
+       {
+       int on = 1;
 
 
-/* test to see if server command parser understands TELNET SYNC command */
+       if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on))
+               < 0 && debug) {
+                       perror("ftp: setsockopt");
+               }
+       }
+#endif SO_OOBINLINE
 
 
-       fprintf(cout,"%c%c",IAC,NOP);
-       (void) fflush(cout);
-       *msg = IAC;
-       *(msg+1) = DM;
-       if (send(s,msg,2,MSG_OOB) != 2)
-               perror("sync");
-       oldverbose = verbose;
-       if (!debug)
-               verbose = -1;
-       if (command("NOOP") == COMPLETE)
-               telflag = 1;
-       else
-               telflag = 0;
-       verbose = oldverbose;
        return (hostname);
 bad:
        return (hostname);
 bad:
-       close(s);
+       (void) close(s);
        return ((char *)0);
 }
 
        return ((char *)0);
 }
 
@@ -152,11 +165,10 @@ login(host)
 
        user = pass = acct = 0;
        if (ruserpass(host, &user, &pass, &acct) < 0) {
 
        user = pass = acct = 0;
        if (ruserpass(host, &user, &pass, &acct) < 0) {
-               disconnect();
                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) {
@@ -165,7 +177,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')
@@ -194,7 +209,7 @@ login(host)
                return(1);
        for (n = 0; n < macnum; ++n) {
                if (!strcmp("init", macros[n].mac_name)) {
                return(1);
        for (n = 0; n < macnum; ++n) {
                if (!strcmp("init", macros[n].mac_name)) {
-                       strcpy(line, "$init");
+                       (void) strcpy(line, "$init");
                        makeargv();
                        domacro(margc, margv);
                        break;
                        makeargv();
                        domacro(margc, margv);
                        break;
@@ -214,16 +229,20 @@ cmdabort()
                longjmp(ptabort,1);
 }
 
                longjmp(ptabort,1);
 }
 
-/*VARARGS 1*/
+/*VARARGS1*/
 command(fmt, args)
        char *fmt;
 {
        int r, (*oldintr)(), cmdabort();
 command(fmt, args)
        char *fmt;
 {
        int r, (*oldintr)(), cmdabort();
+       char *xxx = "XXX";
 
        abrtflag = 0;
        if (debug) {
                printf("---> ");
 
        abrtflag = 0;
        if (debug) {
                printf("---> ");
-               _doprnt(fmt, &args, stdout);
+               if (strncmp(fmt, "PASS", 4) == 0)
+                       _doprnt(fmt, (int *)&xxx, stdout);
+               else
+                       _doprnt(fmt, &args, stdout);
                printf("\n");
                (void) fflush(stdout);
        }
                printf("\n");
                (void) fflush(stdout);
        }
@@ -244,6 +263,8 @@ command(fmt, args)
        return(r);
 }
 
        return(r);
 }
 
+char reply_string[BUFSIZ];             /* last line of previous reply */
+
 #include <ctype.h>
 
 getreply(expecteof)
 #include <ctype.h>
 
 getreply(expecteof)
@@ -251,6 +272,7 @@ getreply(expecteof)
 {
        register int c, n;
        register int dig;
 {
        register int c, n;
        register int dig;
+       register char *cp;
        int originalcode = 0, continuation = 0, (*oldintr)(), cmdabort();
        int pflag = 0;
        char *pt = pasv;
        int originalcode = 0, continuation = 0, (*oldintr)(), cmdabort();
        int pflag = 0;
        char *pt = pasv;
@@ -258,7 +280,27 @@ getreply(expecteof)
        oldintr = signal(SIGINT,cmdabort);
        for (;;) {
                dig = n = code = 0;
        oldintr = signal(SIGINT,cmdabort);
        for (;;) {
                dig = n = code = 0;
+               cp = reply_string;
                while ((c = getc(cin)) != '\n') {
                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);
+                                       (void) fflush(cout);
+                                       break;
+                               case DO:
+                               case DONT:
+                                       c = getc(cin);
+                                       fprintf(cout, "%c%c%c",IAC,WONT,c);
+                                       (void) fflush(cout);
+                                       break;
+                               default:
+                                       break;
+                               }
+                               continue;
+                       }
                        dig++;
                        if (c == EOF) {
                                if (expecteof) {
                        dig++;
                        if (c == EOF) {
                                if (expecteof) {
@@ -270,16 +312,16 @@ getreply(expecteof)
                                if (verbose) {
                                        printf("421 Service not available, remote server has closed connection\n");
                                        (void) fflush(stdout);
                                if (verbose) {
                                        printf("421 Service not available, remote server has closed connection\n");
                                        (void) fflush(stdout);
-                                       code = 421;
-                                       return(4);
                                }
                                }
+                               code = 421;
+                               return(4);
                        }
                        if (c != '\r' && (verbose > 0 ||
                            (verbose > -1 && n == '5' && dig > 4))) {
                                if (proxflag &&
                                   (dig == 1 || dig == 5 && verbose == 0))
                                        printf("%s:",hostname);
                        }
                        if (c != '\r' && (verbose > 0 ||
                            (verbose > -1 && n == '5' && dig > 4))) {
                                if (proxflag &&
                                   (dig == 1 || dig == 5 && verbose == 0))
                                        printf("%s:",hostname);
-                               putchar(c);
+                               (void) putchar(c);
                        }
                        if (dig < 4 && isdigit(c))
                                code = code * 10 + (c - '0');
                        }
                        if (dig < 4 && isdigit(c))
                                code = code * 10 + (c - '0');
@@ -302,9 +344,11 @@ getreply(expecteof)
                        }
                        if (n == 0)
                                n = c;
                        }
                        if (n == 0)
                                n = c;
+                       if (cp < &reply_string[sizeof(reply_string) - 1])
+                               *cp++ = c;
                }
                if (verbose > 0 || verbose > -1 && n == '5') {
                }
                if (verbose > 0 || verbose > -1 && n == '5') {
-                       putchar(c);
+                       (void) putchar(c);
                        (void) fflush (stdout);
                }
                if (continuation && code != originalcode) {
                        (void) fflush (stdout);
                }
                if (continuation && code != originalcode) {
@@ -312,6 +356,7 @@ getreply(expecteof)
                                originalcode = code;
                        continue;
                }
                                originalcode = code;
                        continue;
                }
+               *cp = '\0';
                if (n != '1')
                        cpend = 0;
                (void) signal(SIGINT,oldintr);
                if (n != '1')
                        cpend = 0;
                (void) signal(SIGINT,oldintr);
@@ -324,16 +369,14 @@ getreply(expecteof)
 }
 
 empty(mask, sec)
 }
 
 empty(mask, sec)
-       long mask;
+       struct fd_set *mask;
        int sec;
 {
        struct timeval t;
 
        t.tv_sec = (long) sec;
        t.tv_usec = 0;
        int sec;
 {
        struct timeval t;
 
        t.tv_sec = (long) sec;
        t.tv_usec = 0;
-       if (select(20, &mask, 0, 0, &t) < 0)
-               return(-1);
-       return (mask);
+       return(select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t));
 }
 
 jmp_buf        sendabort;
 }
 
 jmp_buf        sendabort;
@@ -348,25 +391,38 @@ abortsend()
        longjmp(sendabort, 1);
 }
 
        longjmp(sendabort, 1);
 }
 
-sendrequest(cmd, local, remote)
+#define HASHBYTES 1024
+
+sendrequest(cmd, local, remote, printnames)
        char *cmd, *local, *remote;
        char *cmd, *local, *remote;
+       int printnames;
 {
        FILE *fin, *dout = 0, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)();
        int abortsend();
 {
        FILE *fin, *dout = 0, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)();
        int abortsend();
-       char buf[BUFSIZ];
-       long bytes = 0, hashbytes = sizeof (buf);
+       char buf[BUFSIZ], *bufp;
+       long bytes = 0, hashbytes = HASHBYTES;
        register int c, d;
        struct stat st;
        struct timeval start, stop;
        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;
+       mode = "w";
        if (setjmp(sendabort)) {
                while (cpend) {
                        (void) getreply(0);
        if (setjmp(sendabort)) {
                while (cpend) {
                        (void) getreply(0);
@@ -407,8 +463,9 @@ sendrequest(cmd, local, remote)
                closefunc = fclose;
                if (fstat(fileno(fin), &st) < 0 ||
                    (st.st_mode&S_IFMT) != S_IFREG) {
                closefunc = fclose;
                if (fstat(fileno(fin), &st) < 0 ||
                    (st.st_mode&S_IFMT) != S_IFREG) {
-                       fprintf(stderr, "%s: not a plain file.\n", local);
+                       fprintf(stdout, "%s: not a plain file.\n", local);
                        (void) signal(SIGINT, oldintr);
                        (void) signal(SIGINT, oldintr);
+                       fclose(fin);
                        code = -1;
                        return;
                }
                        code = -1;
                        return;
                }
@@ -418,15 +475,20 @@ sendrequest(cmd, local, remote)
                if (oldintp)
                        (void) signal(SIGPIPE, oldintp);
                code = -1;
                if (oldintp)
                        (void) signal(SIGPIPE, oldintp);
                code = -1;
+               if (closefunc != NULL)
+                       (*closefunc)(fin);
                return;
        }
        if (setjmp(sendabort))
                goto abort;
                return;
        }
        if (setjmp(sendabort))
                goto abort;
+
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
                        if (oldintp)
                                (void) signal(SIGPIPE, oldintp);
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
                        if (oldintp)
                                (void) signal(SIGPIPE, oldintp);
+                       if (closefunc != NULL)
+                               (*closefunc)(fin);
                        return;
                }
        } else
                        return;
                }
        } else
@@ -434,79 +496,101 @@ sendrequest(cmd, local, remote)
                        (void) signal(SIGINT, oldintr);
                        if (oldintp)
                                (void) signal(SIGPIPE, oldintp);
                        (void) signal(SIGINT, oldintr);
                        if (oldintp)
                                (void) signal(SIGPIPE, oldintp);
+                       if (closefunc != NULL)
+                               (*closefunc)(fin);
                        return;
                }
                        return;
                }
-       dout = dataconn("w");
+       dout = dataconn(mode);
        if (dout == NULL)
                goto abort;
        if (dout == NULL)
                goto abort;
-       gettimeofday(&start, (struct timezone *)0);
+       (void) gettimeofday(&start, (struct timezone *)0);
+       oldintp = signal(SIGPIPE, SIG_IGN);
        switch (type) {
 
        case TYPE_I:
        case TYPE_L:
                errno = d = 0;
        switch (type) {
 
        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)) < 0)
-                               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) {
                        if (hash) {
-                               putchar('#');
-                               fflush(stdout);
+                               while (bytes >= hashbytes) {
+                                       (void) putchar('#');
+                                       hashbytes += HASHBYTES;
+                               }
+                               (void) fflush(stdout);
                        }
                }
                if (hash && bytes > 0) {
                        }
                }
                if (hash && bytes > 0) {
-                       putchar('\n');
-                       fflush(stdout);
+                       if (bytes < HASHBYTES)
+                               (void) putchar('#');
+                       (void) putchar('\n');
+                       (void) fflush(stdout);
                }
                if (c < 0)
                        perror(local);
                }
                if (c < 0)
                        perror(local);
-               if (d < 0)
-                       perror("netout");
+               if (d <= 0) {
+                       if (d == 0)
+                               fprintf(stderr, "netout: write returned 0?\n");
+                       else if (errno != EPIPE) 
+                               perror("netout");
+                       bytes = -1;
+               }
                break;
 
        case TYPE_A:
                while ((c = getc(fin)) != EOF) {
                        if (c == '\n') {
                                while (hash && (bytes >= hashbytes)) {
                break;
 
        case TYPE_A:
                while ((c = getc(fin)) != EOF) {
                        if (c == '\n') {
                                while (hash && (bytes >= hashbytes)) {
-                                       putchar('#');
-                                       fflush(stdout);
-                                       hashbytes += sizeof (buf);
+                                       (void) putchar('#');
+                                       (void) fflush(stdout);
+                                       hashbytes += HASHBYTES;
                                }
                                if (ferror(dout))
                                        break;
                                }
                                if (ferror(dout))
                                        break;
-                               putc('\r', dout);
+                               (void) putc('\r', dout);
                                bytes++;
                        }
                                bytes++;
                        }
-                       putc(c, dout);
+                       (void) putc(c, dout);
                        bytes++;
        /*              if (c == '\r') {                                */
                        bytes++;
        /*              if (c == '\r') {                                */
-       /*                      putc('\0', dout);  /* this violates rfc */
+       /*              (void)  putc('\0', dout);  /* this violates rfc */
        /*                      bytes++;                                */
        /*              }                                               */      
                }
                if (hash) {
                        if (bytes < hashbytes)
        /*                      bytes++;                                */
        /*              }                                               */      
                }
                if (hash) {
                        if (bytes < hashbytes)
-                               putchar('#');
-                       putchar('\n');
-                       fflush(stdout);
+                               (void) putchar('#');
+                       (void) putchar('\n');
+                       (void) fflush(stdout);
                }
                if (ferror(fin))
                        perror(local);
                }
                if (ferror(fin))
                        perror(local);
-               if (ferror(dout))
-                       perror("netout");
+               if (ferror(dout)) {
+                       if (errno != EPIPE)
+                               perror("netout");
+                       bytes = -1;
+               }
                break;
        }
                break;
        }
-       gettimeofday(&stop, (struct timezone *)0);
+       (void) gettimeofday(&stop, (struct timezone *)0);
        if (closefunc != NULL)
                (*closefunc)(fin);
        (void) fclose(dout);
        (void) getreply(0);
        (void) signal(SIGINT, oldintr);
        if (closefunc != NULL)
                (*closefunc)(fin);
        (void) fclose(dout);
        (void) getreply(0);
        (void) signal(SIGINT, oldintr);
-       if (bytes > 0 && verbose)
-               ptransfer("sent", bytes, &start, &stop, local, remote);
+       if (oldintp)
+               (void) signal(SIGPIPE, oldintp);
+       if (bytes > 0)
+               ptransfer("sent", bytes, &start, &stop);
        return;
 abort:
        return;
 abort:
-       gettimeofday(&stop, (struct timezone *)0);
+       (void) gettimeofday(&stop, (struct timezone *)0);
        (void) signal(SIGINT, oldintr);
        if (oldintp)
                (void) signal(SIGPIPE, oldintp);
        (void) signal(SIGINT, oldintr);
        if (oldintp)
                (void) signal(SIGPIPE, oldintp);
@@ -524,8 +608,8 @@ abort:
        code = -1;
        if (closefunc != NULL && fin != NULL)
                (*closefunc)(fin);
        code = -1;
        if (closefunc != NULL && fin != NULL)
                (*closefunc)(fin);
-       if (bytes > 0 && verbose)
-               ptransfer("sent", bytes, &start, &stop, local, remote);
+       if (bytes > 0)
+               ptransfer("sent", bytes, &start, &stop);
 }
 
 jmp_buf        recvabort;
 }
 
 jmp_buf        recvabort;
@@ -540,25 +624,37 @@ abortrecv()
        longjmp(recvabort, 1);
 }
 
        longjmp(recvabort, 1);
 }
 
-recvrequest(cmd, local, remote, mode)
+recvrequest(cmd, local, remote, mode, printnames)
        char *cmd, *local, *remote, *mode;
 {
        FILE *fout, *din = 0, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)(); 
        char *cmd, *local, *remote, *mode;
 {
        FILE *fout, *din = 0, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)(); 
-       int abortrecv(), oldverbose, oldtype = 0, tcrflag;
-       char buf[BUFSIZ], *gunique();
-       long bytes = 0, hashbytes = sizeof (buf), mask;
+       int abortrecv(), is_retr, tcrflag, nfnd;
+       char *bufp, *gunique(), msg;
+       static char *buf;
+       static int bufsize;
+       long bytes = 0, hashbytes = HASHBYTES;
+       struct fd_set mask;
        register int c, d;
        struct timeval start, stop;
        register int c, d;
        struct timeval start, stop;
+       struct stat st;
+       extern char *malloc();
 
 
-       if (proxy && strcmp(cmd,"RETR") == 0) {
+       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;
        }
        closefunc = NULL;
        oldintr = NULL;
        oldintp = NULL;
                proxtrans(cmd, local, remote);
                return;
        }
        closefunc = NULL;
        oldintr = NULL;
        oldintp = NULL;
-       tcrflag = !crflag && !strcmp(cmd, "RETR");
+       tcrflag = !crflag && is_retr;
        if (setjmp(recvabort)) {
                while (cpend) {
                        (void) getreply(0);
        if (setjmp(recvabort)) {
                while (cpend) {
                        (void) getreply(0);
@@ -595,7 +691,7 @@ recvrequest(cmd, local, remote, mode)
                                return;
                        }
                        if (!runique && errno == EACCES &&
                                return;
                        }
                        if (!runique && errno == EACCES &&
-                           chmod(local,0600) < 0) {
+                           chmod(local, 0600) < 0) {
                                perror(local);
                                (void) signal(SIGINT, oldintr);
                                code = -1;
                                perror(local);
                                (void) signal(SIGINT, oldintr);
                                code = -1;
@@ -614,6 +710,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;
@@ -621,54 +722,17 @@ recvrequest(cmd, local, remote, mode)
        }
        if (setjmp(recvabort))
                goto abort;
        }
        if (setjmp(recvabort))
                goto abort;
-       if (strcmp(cmd, "RETR") && type != TYPE_A) {
-               oldtype = type;
-               oldverbose = verbose;
-               if (!debug)
-                       verbose = 0;
-               setascii();
-               verbose = oldverbose;
-       }
+       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;
                }
        }
@@ -685,8 +749,7 @@ recvrequest(cmd, local, remote, mode)
                        goto abort;
                }
                closefunc = pclose;
                        goto abort;
                }
                closefunc = pclose;
-       }
-       else {
+       } else {
                fout = fopen(local, mode);
                if (fout == NULL) {
                        perror(local);
                fout = fopen(local, mode);
                if (fout == NULL) {
                        perror(local);
@@ -694,146 +757,155 @@ recvrequest(cmd, local, remote, mode)
                }
                closefunc = fclose;
        }
                }
                closefunc = fclose;
        }
-       gettimeofday(&start, (struct timezone *)0);
-       switch (type) {
+       if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)
+               st.st_blksize = BUFSIZ;
+       if (st.st_blksize > bufsize) {
+               if (buf)
+                       (void) free(buf);
+               buf = malloc(st.st_blksize);
+               if (buf == NULL) {
+                       perror("malloc");
+                       bufsize = 0;
+                       bufsize = 0;
+                       goto abort;
+               }
+               bufsize = st.st_blksize;
+       }
+       (void) gettimeofday(&start, (struct timezone *)0);
+       switch (curtype) {
 
        case TYPE_I:
        case TYPE_L:
                errno = d = 0;
 
        case TYPE_I:
        case TYPE_L:
                errno = d = 0;
-               while ((c = read(fileno(din), buf, sizeof (buf))) > 0) {
-                       if ((d = write(fileno(fout), buf, c)) < 0)
+               while ((c = read(fileno(din), buf, bufsize)) > 0) {
+                       if ((d = write(fileno(fout), buf, c)) != c)
                                break;
                        bytes += c;
                        if (hash) {
                                break;
                        bytes += c;
                        if (hash) {
-                               putchar('#');
-                               fflush(stdout);
+                               while (bytes >= hashbytes) {
+                                       (void) putchar('#');
+                                       hashbytes += HASHBYTES;
+                               }
+                               (void) fflush(stdout);
                        }
                }
                if (hash && bytes > 0) {
                        }
                }
                if (hash && bytes > 0) {
-                       putchar('\n');
-                       fflush(stdout);
+                       if (bytes < HASHBYTES)
+                               (void) putchar('#');
+                       (void) putchar('\n');
+                       (void) fflush(stdout);
+               }
+               if (c < 0) {
+                       if (errno != EPIPE)
+                               perror("netin");
+                       bytes = -1;
+               }
+               if (d < c) {
+                       if (d < 0)
+                               perror(local);
+                       else
+                               fprintf(stderr, "%s: short write\n", local);
                }
                }
-               if (c < 0)
-                       perror("netin");
-               if (d < 0)
-                       perror(local);
                break;
 
        case TYPE_A:
                while ((c = getc(din)) != EOF) {
                break;
 
        case TYPE_A:
                while ((c = getc(din)) != EOF) {
-                       if (c == '\r') {
+                       while (c == '\r') {
                                while (hash && (bytes >= hashbytes)) {
                                while (hash && (bytes >= hashbytes)) {
-                                       putchar('#');
-                                       fflush(stdout);
-                                       hashbytes += sizeof (buf);
+                                       (void) putchar('#');
+                                       (void) fflush(stdout);
+                                       hashbytes += HASHBYTES;
                                }
                                bytes++;
                                if ((c = getc(din)) != '\n' || tcrflag) {
                                }
                                bytes++;
                                if ((c = getc(din)) != '\n' || tcrflag) {
-                                       if (ferror (fout))
-                                               break;
-                                       putc ('\r', fout);
+                                       if (ferror(fout))
+                                               goto break2;
+                                       (void) putc('\r', fout);
+                                       if (c == '\0') {
+                                               bytes++;
+                                               goto contin2;
+                                       }
+                                       if (c == EOF)
+                                               goto contin2;
+                                       }
+                                       if (c == EOF)
+                                               goto contin2;
                                }
                                }
-                               /*if (c == '\0') {
-                                       bytes++;
-                                       continue;
-                               }*/
                        }
                        }
-                       putc (c, fout);
+                       (void) putc(c, fout);
                        bytes++;
                        bytes++;
+       contin2:        ;
                }
                }
+break2:
                if (hash) {
                        if (bytes < hashbytes)
                if (hash) {
                        if (bytes < hashbytes)
-                               putchar('#');
-                       putchar('\n');
-                       fflush(stdout);
+                               (void) putchar('#');
+                       (void) putchar('\n');
+                       (void) fflush(stdout);
                }
                }
-               if (ferror (din))
-                       perror ("netin");
-               if (ferror (fout))
-                       perror (local);
+               if (ferror(din)) {
+                       if (errno != EPIPE)
+                               perror("netin");
+                       bytes = -1;
+               }
+               if (ferror(fout))
+                       perror(local);
                break;
        }
        if (closefunc != NULL)
                (*closefunc)(fout);
                break;
        }
        if (closefunc != NULL)
                (*closefunc)(fout);
-       signal(SIGINT, oldintr);
+       (void) signal(SIGINT, oldintr);
        if (oldintp)
                (void) signal(SIGPIPE, oldintp);
        if (oldintp)
                (void) signal(SIGPIPE, oldintp);
-       gettimeofday(&stop, (struct timezone *)0);
+       (void) gettimeofday(&stop, (struct timezone *)0);
        (void) fclose(din);
        (void) getreply(0);
        (void) fclose(din);
        (void) getreply(0);
-       if (bytes > 0 && verbose)
-               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;
-       }
+       if (bytes > 0 && is_retr)
+               ptransfer("received", bytes, &start, &stop);
        return;
 abort:
 
        return;
 abort:
 
-/* if server command parser understands TELNET commands, abort using */
-/* recommended IP,SYNC sequence                                      */
+/* abort using RFC959 recommended IP,SYNC sequence  */
 
 
-       gettimeofday(&stop, (struct timezone *)0);
+       (void) gettimeofday(&stop, (struct timezone *)0);
        if (oldintp)
                (void) signal(SIGPIPE, oldintr);
        (void) signal(SIGINT,SIG_IGN);
        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;
-       }
        if (!cpend) {
                code = -1;
                (void) signal(SIGINT,oldintr);
                return;
        }
        if (!cpend) {
                code = -1;
                (void) signal(SIGINT,oldintr);
                return;
        }
-       if (telflag) {
-               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,"%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,"ABOR\r\n");
+       fprintf(cout,"%cABOR\r\n",DM);
        (void) fflush(cout);
        (void) fflush(cout);
-       mask = (1 << fileno(cin)) | (din ? (1 << fileno(din)) : 0);
-       if ((mask = empty(mask,10)) < 0) {
-               perror("abort");
+       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();
        }
                code = -1;
                lostpeer();
        }
-       if (din && mask & (1 << fileno(din)))
-               while ((c = read(fileno(din), buf, sizeof (buf))) > 0)
+       if (din && FD_ISSET(fileno(din), &mask)) {
+               while ((c = read(fileno(din), buf, bufsize)) > 0)
                        ;
                        ;
-       if ((c = getreply(0)) == ERROR) { /* needed for nic style abort */
+       }
+       if ((c = getreply(0)) == ERROR && code == 552) { /* needed for nic style abort */
                if (data >= 0) {
                if (data >= 0) {
-                       close(data);
+                       (void) close(data);
                        data = -1;
                }
                (void) getreply(0);
                        data = -1;
                }
                (void) getreply(0);
@@ -848,8 +920,8 @@ abort:
                (*closefunc)(fout);
        if (din)
                (void) fclose(din);
                (*closefunc)(fout);
        if (din)
                (void) fclose(din);
-       if (bytes > 0 && verbose)
-               ptransfer("received", bytes, &start, &stop, local, remote);
+       if (bytes > 0)
+               ptransfer("received", bytes, &start, &stop);
        (void) signal(SIGINT,oldintr);
 }
 
        (void) signal(SIGINT,oldintr);
 }
 
@@ -858,7 +930,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.
  */
-static int sendport = -1;
+int sendport = -1;
 
 initconn()
 {
 
 initconn()
 {
@@ -880,16 +952,16 @@ noport:
                return (1);
        }
        if (!sendport)
                return (1);
        }
        if (!sendport)
-               if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) {
-                       perror("ftp: setsockopt (resuse address)");
+               if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
+                       perror("ftp: setsockopt (reuse address)");
                        goto bad;
                }
                        goto bad;
                }
-       if (bind(data, (char *)&data_addr, sizeof (data_addr), 0) < 0) {
+       if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
                perror("ftp: bind");
                goto bad;
        }
        if (options & SO_DEBUG &&
                perror("ftp: bind");
                goto bad;
        }
        if (options & SO_DEBUG &&
-           setsockopt(data, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)) < 0)
+           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) {
                perror("ftp: setsockopt (ignored)");
        len = sizeof (data_addr);
        if (getsockname(data, (char *)&data_addr, &len) < 0) {
@@ -930,7 +1002,7 @@ dataconn(mode)
        struct sockaddr_in from;
        int s, fromlen = sizeof (from);
 
        struct sockaddr_in from;
        int s, fromlen = sizeof (from);
 
-       s = accept(data, &from, &fromlen, 0);
+       s = accept(data, (struct sockaddr *) &from, &fromlen);
        if (s < 0) {
                perror("ftp: accept");
                (void) close(data), data = -1;
        if (s < 0) {
                perror("ftp: accept");
                (void) close(data), data = -1;
@@ -941,27 +1013,25 @@ 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;
 {
        struct timeval td;
        float s, bs;
 
        long bytes;
        struct timeval *t0, *t1;
 {
        struct timeval td;
        float s, bs;
 
-       tvsub(&td, t1, t0);
-       s = td.tv_sec + (td.tv_usec / 1000000.);
+       if (verbose) {
+               tvsub(&td, t1, t0);
+               s = td.tv_sec + (td.tv_usec / 1000000.);
 #define        nz(x)   ((x) == 0 ? 1 : (x))
 #define        nz(x)   ((x) == 0 ? 1 : (x))
-       bs = bytes / nz(s);
-       if (local && *local != '-')
-               printf("local: %s ", local);
-       if (remote)
-               printf("remote: %s\n", remote);
-       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.);
+       }
 }
 
 }
 
-tvadd(tsum, t0)
+/*tvadd(tsum, t0)
        struct timeval *tsum, *t0;
 {
 
        struct timeval *tsum, *t0;
 {
 
@@ -969,7 +1039,7 @@ tvadd(tsum, t0)
        tsum->tv_usec += t0->tv_usec;
        if (tsum->tv_usec > 1000000)
                tsum->tv_sec++, tsum->tv_usec -= 1000000;
        tsum->tv_usec += t0->tv_usec;
        if (tsum->tv_usec > 1000000)
                tsum->tv_sec++, tsum->tv_usec -= 1000000;
-}
+} */
 
 tvsub(tdiff, t1, t0)
        struct timeval *tdiff, *t1, *t0;
 
 tvsub(tdiff, t1, t0)
        struct timeval *tdiff, *t1, *t0;
@@ -995,13 +1065,13 @@ pswitch(flag)
        int (*oldintr)();
        static struct comvars {
                int connect;
        int (*oldintr)();
        static struct comvars {
                int connect;
-               char name[32];
+               char name[MAXHOSTNAMELEN];
                struct sockaddr_in mctl;
                struct sockaddr_in hctl;
                FILE *in;
                FILE *out;
                struct sockaddr_in mctl;
                struct sockaddr_in hctl;
                FILE *in;
                FILE *out;
-               int tflag;
                int tpe;
                int tpe;
+               int curtpe;
                int cpnd;
                int sunqe;
                int runqe;
                int cpnd;
                int sunqe;
                int runqe;
@@ -1012,7 +1082,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;
@@ -1023,8 +1093,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;
@@ -1033,8 +1102,11 @@ pswitch(flag)
        }
        ip->connect = connected;
        connected = op->connect;
        }
        ip->connect = connected;
        connected = op->connect;
-       strncpy(ip->name, hostname, 31);
-       (ip->name)[strlen(ip->name)] = '\0';
+       if (hostname) {
+               (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
+               ip->name[strlen(ip->name)] = '\0';
+       } else
+               ip->name[0] = 0;
        hostname = op->name;
        ip->hctl = hisctladdr;
        hisctladdr = op->hctl;
        hostname = op->name;
        ip->hctl = hisctladdr;
        hisctladdr = op->hctl;
@@ -1044,12 +1116,10 @@ pswitch(flag)
        cin = op->in;
        ip->out = cout;
        cout = op->out;
        cin = op->in;
        ip->out = cout;
        cout = op->out;
-       ip->tflag = telflag;
-       telflag = op->tflag;
        ip->tpe = type;
        type = op->tpe;
        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;
@@ -1060,20 +1130,20 @@ pswitch(flag)
        mcase = op->mcse;
        ip->ntflg = ntflag;
        ntflag = op->ntflg;
        mcase = op->mcse;
        ip->ntflg = ntflag;
        ntflag = op->ntflg;
-       strncpy(ip->nti, ntin, 16);
+       (void) strncpy(ip->nti, ntin, 16);
        (ip->nti)[strlen(ip->nti)] = '\0';
        (ip->nti)[strlen(ip->nti)] = '\0';
-       strcpy(ntin, op->nti);
-       strncpy(ip->nto, ntout, 16);
+       (void) strcpy(ntin, op->nti);
+       (void) strncpy(ip->nto, ntout, 16);
        (ip->nto)[strlen(ip->nto)] = '\0';
        (ip->nto)[strlen(ip->nto)] = '\0';
-       strcpy(ntout, op->nto);
+       (void) strcpy(ntout, op->nto);
        ip->mapflg = mapflag;
        mapflag = op->mapflg;
        ip->mapflg = mapflag;
        mapflag = op->mapflg;
-       strncpy(ip->mi, mapin, MAXPATHLEN - 1);
+       (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
        (ip->mi)[strlen(ip->mi)] = '\0';
        (ip->mi)[strlen(ip->mi)] = '\0';
-       strcpy(mapin, op->mi);
-       strncpy(ip->mo, mapout, MAXPATHLEN - 1);
+       (void) strcpy(mapin, op->mi);
+       (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
        (ip->mo)[strlen(ip->mo)] = '\0';
        (ip->mo)[strlen(ip->mo)] = '\0';
-       strcpy(mapout, op->mo);
+       (void) strcpy(mapout, op->mo);
        (void) signal(SIGINT, oldintr);
        if (abrtflag) {
                abrtflag = 0;
        (void) signal(SIGINT, oldintr);
        if (abrtflag) {
                abrtflag = 0;
@@ -1087,7 +1157,7 @@ int ptabflg;
 abortpt()
 {
        printf("\n");
 abortpt()
 {
        printf("\n");
-       fflush(stdout);
+       (void) fflush(stdout);
        ptabflg++;
        mflag = 0;
        abrtflag = 0;
        ptabflg++;
        mflag = 0;
        abrtflag = 0;
@@ -1097,20 +1167,27 @@ 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;
+       int (*oldintr)(), abortpt(), prox_type, secndflag = 0, nfnd;
        extern jmp_buf ptabort;
        char *cmd2;
        extern jmp_buf ptabort;
        char *cmd2;
-       long mask;
+       struct fd_set mask;
 
        if (strcmp(cmd, "RETR"))
                cmd2 = "RETR";
        else
                cmd2 = runique ? "STOU" : "STOR";
 
        if (strcmp(cmd, "RETR"))
                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");
@@ -1118,40 +1195,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;
        }
@@ -1160,22 +1206,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;
        }
@@ -1189,22 +1219,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);
@@ -1219,23 +1233,7 @@ 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 && telflag) {
+                       if (cpend) {
                                char msg[2];
 
                                fprintf(cout,"%c%c",IAC,IP);
                                char msg[2];
 
                                fprintf(cout,"%c%c",IAC,IP);
@@ -1244,13 +1242,14 @@ abort:
                                *(msg+1) = DM;
                                if (send(fileno(cout),msg,2,MSG_OOB) != 2)
                                        perror("abort");
                                *(msg+1) = DM;
                                if (send(fileno(cout),msg,2,MSG_OOB) != 2)
                                        perror("abort");
-                       }
-                       if (cpend) {
                                fprintf(cout,"ABOR\r\n");
                                (void) fflush(cout);
                                fprintf(cout,"ABOR\r\n");
                                (void) fflush(cout);
-                               mask = 1 << fileno(cin);
-                               if ((mask = empty(mask,10)) < 0) {
-                                       perror("abort");
+                               FD_ZERO(&mask);
+                               FD_SET(fileno(cin), &mask);
+                               if ((nfnd = empty(&mask,10)) <= 0) {
+                                       if (nfnd < 0) {
+                                               perror("abort");
+                                       }
                                        if (ptabflg)
                                                code = -1;
                                        lostpeer();
                                        if (ptabflg)
                                                code = -1;
                                        lostpeer();
@@ -1265,7 +1264,7 @@ abort:
                (void) signal(SIGINT, oldintr);
                return;
        }
                (void) signal(SIGINT, oldintr);
                return;
        }
-       if (cpend && telflag) {
+       if (cpend) {
                char msg[2];
 
                fprintf(cout,"%c%c",IAC,IP);
                char msg[2];
 
                fprintf(cout,"%c%c",IAC,IP);
@@ -1274,13 +1273,14 @@ abort:
                *(msg+1) = DM;
                if (send(fileno(cout),msg,2,MSG_OOB) != 2)
                        perror("abort");
                *(msg+1) = DM;
                if (send(fileno(cout),msg,2,MSG_OOB) != 2)
                        perror("abort");
-       }
-       if (cpend) {
                fprintf(cout,"ABOR\r\n");
                (void) fflush(cout);
                fprintf(cout,"ABOR\r\n");
                (void) fflush(cout);
-               mask = 1 << fileno(cin);
-               if ((mask = empty(mask,10)) < 0) {
-                       perror("abort");
+               FD_ZERO(&mask);
+               FD_SET(fileno(cin), &mask);
+               if ((nfnd = empty(&mask,10)) <= 0) {
+                       if (nfnd < 0) {
+                               perror("abort");
+                       }
                        if (ptabflg)
                                code = -1;
                        lostpeer();
                        if (ptabflg)
                                code = -1;
                        lostpeer();
@@ -1292,23 +1292,7 @@ abort:
        if (!cpend && !secndflag) {  /* only if cmd = "RETR" (proxy=1) */
                if (command("%s %s", cmd2, local) != PRELIM) {
                        pswitch(0);
        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 && telflag) {
+                       if (cpend) {
                                char msg[2];
 
                                fprintf(cout,"%c%c",IAC,IP);
                                char msg[2];
 
                                fprintf(cout,"%c%c",IAC,IP);
@@ -1317,13 +1301,14 @@ abort:
                                *(msg+1) = DM;
                                if (send(fileno(cout),msg,2,MSG_OOB) != 2)
                                        perror("abort");
                                *(msg+1) = DM;
                                if (send(fileno(cout),msg,2,MSG_OOB) != 2)
                                        perror("abort");
-                       }
-                       if (cpend) {
                                fprintf(cout,"ABOR\r\n");
                                (void) fflush(cout);
                                fprintf(cout,"ABOR\r\n");
                                (void) fflush(cout);
-                               mask = 1 << fileno(cin);
-                               if ((mask = empty(mask,10)) < 0) {
-                                       perror("abort");
+                               FD_ZERO(&mask);
+                               FD_SET(fileno(cin), &mask);
+                               if ((nfnd = empty(&mask,10)) <= 0) {
+                                       if (nfnd < 0) {
+                                               perror("abort");
+                                       }
                                        if (ptabflg)
                                                code = -1;
                                        lostpeer();
                                        if (ptabflg)
                                                code = -1;
                                        lostpeer();
@@ -1338,7 +1323,7 @@ abort:
                        return;
                }
        }
                        return;
                }
        }
-       if (cpend && telflag) {
+       if (cpend) {
                char msg[2];
 
                fprintf(cout,"%c%c",IAC,IP);
                char msg[2];
 
                fprintf(cout,"%c%c",IAC,IP);
@@ -1347,13 +1332,14 @@ abort:
                *(msg+1) = DM;
                if (send(fileno(cout),msg,2,MSG_OOB) != 2)
                        perror("abort");
                *(msg+1) = DM;
                if (send(fileno(cout),msg,2,MSG_OOB) != 2)
                        perror("abort");
-       }
-       if (cpend) {
                fprintf(cout,"ABOR\r\n");
                (void) fflush(cout);
                fprintf(cout,"ABOR\r\n");
                (void) fflush(cout);
-               mask = 1 << fileno(cin);
-               if ((mask = empty(mask,10)) < 0) {
-                       perror("abort");
+               FD_ZERO(&mask);
+               FD_SET(fileno(cin), &mask);
+               if ((nfnd = empty(&mask,10)) <= 0) {
+                       if (nfnd < 0) {
+                               perror("abort");
+                       }
                        if (ptabflg)
                                code = -1;
                        lostpeer();
                        if (ptabflg)
                                code = -1;
                        lostpeer();
@@ -1363,9 +1349,12 @@ abort:
        }
        pswitch(!proxy);
        if (cpend) {
        }
        pswitch(!proxy);
        if (cpend) {
-               mask = 1 << fileno(cin);
-               if ((mask = empty(mask,10)) < 0) {
-                       perror("abort");
+               FD_ZERO(&mask);
+               FD_SET(fileno(cin), &mask);
+               if ((nfnd = empty(&mask,10)) <= 0) {
+                       if (nfnd < 0) {
+                               perror("abort");
+                       }
                        if (ptabflg)
                                code = -1;
                        lostpeer();
                        if (ptabflg)
                                code = -1;
                        lostpeer();
@@ -1375,22 +1364,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;
@@ -1399,17 +1372,20 @@ abort:
 
 reset()
 {
 
 reset()
 {
-       long mask;
+       struct fd_set mask;
+       int nfnd = 1;
 
 
-       mask = 1 << fileno(cin);
-       while (mask > 0) {
-               if ((mask = empty(mask,0)) < 0) {
+       FD_ZERO(&mask);
+       while (nfnd > 0) {
+               FD_SET(fileno(cin), &mask);
+               if ((nfnd = empty(&mask,0)) < 0) {
                        perror("reset");
                        code = -1;
                        lostpeer();
                }
                        perror("reset");
                        code = -1;
                        lostpeer();
                }
-               if (mask > 0)
+               else if (nfnd) {
                        (void) getreply(0);
                        (void) getreply(0);
+               }
        }
 }
 
        }
 }