X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/dcd54a7f5521fdd0efd40e7b070c2abd3123a47a..522da3e451a5c5d93d6523b197c81de222ba5402:/usr/src/usr.bin/ftp/ftp.c diff --git a/usr/src/usr.bin/ftp/ftp.c b/usr/src/usr.bin/ftp/ftp.c index 9f76af4b5a..e064bd0da7 100644 --- a/usr/src/usr.bin/ftp/ftp.c +++ b/usr/src/usr.bin/ftp/ftp.c @@ -1,22 +1,12 @@ /* - * Copyright (c) 1985, 1989 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1985, 1989, 1993, 1994 + * The 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. + * %sccs.include.redist.c% */ #ifndef lint -static char sccsid[] = "@(#)ftp.c 5.29 (Berkeley) %G%"; +static char sccsid[] = "@(#)ftp.c 8.3 (Berkeley) %G%"; #endif /* not lint */ #include @@ -27,40 +17,51 @@ static char sccsid[] = "@(#)ftp.c 5.29 (Berkeley) %G%"; #include #include +#include +#include +#include #include #include -#include -#include +#include +#include #include -#include #include +#include #include +#include +#include +#include +#include +#include +#include #include "ftp_var.h" +extern int h_errno; + struct sockaddr_in hisctladdr; struct sockaddr_in data_addr; int data = -1; int abrtflag = 0; +jmp_buf ptabort; +int ptabflg; int ptflag = 0; -int connected; struct sockaddr_in myctladdr; -uid_t getuid(); + FILE *cin, *cout; -FILE *dataconn(); char * hookup(host, port) char *host; int port; { - register struct hostent *hp = 0; - int s,len; + struct hostent *hp = 0; + int s, len, tos; static char hostnamebuf[80]; - bzero((char *)&hisctladdr, sizeof (hisctladdr)); + memset((char *)&hisctladdr, 0, sizeof (hisctladdr)); hisctladdr.sin_addr.s_addr = inet_addr(host); if (hisctladdr.sin_addr.s_addr != -1) { hisctladdr.sin_family = AF_INET; @@ -68,60 +69,64 @@ hookup(host, port) } else { hp = gethostbyname(host); if (hp == NULL) { - fprintf(stderr, "ftp: %s: ", host); - herror((char *)NULL); + warnx("%s: %s", host, hstrerror(h_errno)); code = -1; - return((char *) 0); + return ((char *) 0); } hisctladdr.sin_family = hp->h_addrtype; - bcopy(hp->h_addr_list[0], - (caddr_t)&hisctladdr.sin_addr, hp->h_length); + memmove((caddr_t)&hisctladdr.sin_addr, + hp->h_addr_list[0], hp->h_length); (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf)); } hostname = hostnamebuf; s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); if (s < 0) { - perror("ftp: socket"); + warn("socket"); code = -1; 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; + char *ia; - fprintf(stderr, "ftp: connect to address %s: ", - inet_ntoa(hisctladdr.sin_addr)); + ia = inet_ntoa(hisctladdr.sin_addr); errno = oerrno; - perror((char *) 0); + warn("connect to address %s", ia); hp->h_addr_list++; - bcopy(hp->h_addr_list[0], - (caddr_t)&hisctladdr.sin_addr, hp->h_length); + memmove((caddr_t)&hisctladdr.sin_addr, + hp->h_addr_list[0], hp->h_length); fprintf(stdout, "Trying %s...\n", inet_ntoa(hisctladdr.sin_addr)); (void) close(s); s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); if (s < 0) { - perror("ftp: socket"); + warn("socket"); code = -1; return (0); } continue; } - perror("ftp: connect"); + warn("connect"); code = -1; goto bad; } len = sizeof (myctladdr); - if (getsockname(s, (char *)&myctladdr, &len) < 0) { - perror("ftp: getsockname"); + if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) { + warn("getsockname"); code = -1; goto bad; } +#ifdef IP_TOS + tos = IPTOS_LOWDELAY; + if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) + warn("setsockopt TOS (ignored)"); +#endif cin = fdopen(s, "r"); cout = fdopen(s, "w"); if (cin == NULL || cout == NULL) { - fprintf(stderr, "ftp: fdopen failed.\n"); + warnx("fdopen failed."); if (cin) (void) fclose(cin); if (cout) @@ -143,12 +148,12 @@ hookup(host, port) { int on = 1; - if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)) + if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0 && debug) { - perror("ftp: setsockopt"); + warn("setsockopt"); } } -#endif SO_OOBINLINE +#endif /* SO_OOBINLINE */ return (hostname); bad: @@ -156,17 +161,18 @@ bad: return ((char *)0); } +int login(host) char *host; { char tmp[80]; - char *user, *pass, *acct, *getlogin(), *getpass(); + char *user, *pass, *acct; int n, aflag = 0; user = pass = acct = 0; if (ruserpass(host, &user, &pass, &acct) < 0) { code = -1; - return(0); + return (0); } while (user == NULL) { char *myname = getlogin(); @@ -200,13 +206,13 @@ login(host) n = command("ACCT %s", acct); } if (n != COMPLETE) { - fprintf(stderr, "Login failed.\n"); + warnx("Login failed."); return (0); } if (!aflag && acct != NULL) (void) command("ACCT %s", acct); if (proxy) - return(1); + return (1); for (n = 0; n < macnum; ++n) { if (!strcmp("init", macros[n].mac_name)) { (void) strcpy(line, "$init"); @@ -218,9 +224,9 @@ login(host) return (1); } +void cmdabort() { - extern jmp_buf ptabort; printf("\n"); (void) fflush(stdout); @@ -229,55 +235,63 @@ cmdabort() longjmp(ptabort,1); } -/*VARARGS1*/ -command(fmt, args) - char *fmt; +/*VARARGS*/ +int +command(va_alist) +va_dcl { - int r, (*oldintr)(), cmdabort(); - char *xxx = "XXX"; + va_list ap; + char *fmt; + int r; + sig_t oldintr; abrtflag = 0; if (debug) { printf("---> "); - if (strncmp(fmt, "PASS", 4) == 0) - _doprnt(fmt, (int *)&xxx, stdout); - else - _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); } if (cout == NULL) { - perror ("No control connection for command"); + warn("No control connection for command"); 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; r = getreply(!strcmp(fmt, "QUIT")); if (abrtflag && oldintr != SIG_IGN) - (*oldintr)(); + (*oldintr)(SIGINT); (void) signal(SIGINT, oldintr); - return(r); + return (r); } char reply_string[BUFSIZ]; /* last line of previous reply */ -#include - +int getreply(expecteof) int expecteof; { - register int c, n; - register int dig; - register char *cp; - int originalcode = 0, continuation = 0, (*oldintr)(), cmdabort(); + int c, n; + int dig; + int originalcode = 0, continuation = 0; + sig_t oldintr; int pflag = 0; - char *pt = pasv; + char *cp, *pt = pasv; - oldintr = signal(SIGINT,cmdabort); + oldintr = signal(SIGINT, cmdabort); for (;;) { dig = n = code = 0; cp = reply_string; @@ -287,13 +301,13 @@ getreply(expecteof) 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); - fprintf(cout, "%c%c%c",IAC,WONT,c); + fprintf(cout, "%c%c%c", IAC, WONT, c); (void) fflush(cout); break; default: @@ -314,7 +328,7 @@ getreply(expecteof) (void) fflush(stdout); } code = 421; - return(4); + return (4); } if (c != '\r' && (verbose > 0 || (verbose > -1 && n == '5' && dig > 4))) { @@ -363,11 +377,12 @@ getreply(expecteof) if (code == 421 || originalcode == 421) lostpeer(); if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN) - (*oldintr)(); + (*oldintr)(SIGINT); return (n - '0'); } } +int empty(mask, sec) struct fd_set *mask; int sec; @@ -376,36 +391,37 @@ empty(mask, sec) t.tv_sec = (long) sec; t.tv_usec = 0; - return(select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t)); + return (select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t)); } jmp_buf sendabort; +void abortsend() { 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 sendrequest(cmd, local, remote, printnames) char *cmd, *local, *remote; int printnames; { + struct stat st; + struct timeval start, stop; + int c, d; FILE *fin, *dout = 0, *popen(); - int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)(); - int abortsend(); + int (*closefunc) __P((FILE *)); char buf[BUFSIZ], *bufp; long bytes = 0, hashbytes = HASHBYTES; - register int c, d; - struct stat st; - struct timeval start, stop; - char *mode; + char *lmode, buf[BUFSIZ], *bufp; if (verbose && printnames) { if (local && *local != '-') @@ -422,7 +438,7 @@ sendrequest(cmd, local, remote, printnames) closefunc = NULL; oldintr = NULL; oldintp = NULL; - mode = "w"; + lmode = "w"; if (setjmp(sendabort)) { while (cpend) { (void) getreply(0); @@ -445,7 +461,7 @@ sendrequest(cmd, local, remote, printnames) oldintp = signal(SIGPIPE,SIG_IGN); fin = popen(local + 1, "r"); if (fin == NULL) { - perror(local + 1); + warn("%s", local + 1); (void) signal(SIGINT, oldintr); (void) signal(SIGPIPE, oldintp); code = -1; @@ -455,7 +471,7 @@ sendrequest(cmd, local, remote, printnames) } else { fin = fopen(local, "r"); if (fin == NULL) { - perror(local); + warn("local: %s", local); (void) signal(SIGINT, oldintr); code = -1; return; @@ -500,12 +516,12 @@ sendrequest(cmd, local, remote, printnames) (*closefunc)(fin); return; } - dout = dataconn(mode); + dout = dataconn(lmode); if (dout == NULL) goto abort; (void) gettimeofday(&start, (struct timezone *)0); oldintp = signal(SIGPIPE, SIG_IGN); - switch (type) { + switch (curtype) { case TYPE_I: case TYPE_L: @@ -533,12 +549,12 @@ sendrequest(cmd, local, remote, printnames) (void) fflush(stdout); } if (c < 0) - perror(local); + warn("local: %s", local); if (d <= 0) { if (d == 0) fprintf(stderr, "netout: write returned 0?\n"); else if (errno != EPIPE) - perror("netout"); + warn("netout"); bytes = -1; } break; @@ -559,7 +575,7 @@ sendrequest(cmd, local, remote, printnames) (void) putc(c, dout); bytes++; /* if (c == '\r') { */ - /* (void) putc('\0', dout); /* this violates rfc */ + /* (void) putc('\0', dout); // this violates rfc */ /* bytes++; */ /* } */ } @@ -570,10 +586,10 @@ sendrequest(cmd, local, remote, printnames) (void) fflush(stdout); } if (ferror(fin)) - perror(local); + warn("local: %s", local); if (ferror(dout)) { if (errno != EPIPE) - perror("netout"); + warn("netout"); bytes = -1; } break; @@ -614,31 +630,29 @@ abort: jmp_buf recvabort; +void abortrecv() { mflag = 0; abrtflag = 0; - printf("\n"); + printf("\nreceive aborted\nwaiting for remote to finish abort\n"); (void) fflush(stdout); longjmp(recvabort, 1); } -recvrequest(cmd, local, remote, mode, printnames) - char *cmd, *local, *remote, *mode; +void +recvrequest(cmd, local, remote, lmode, printnames) + char *cmd, *local, *remote, *lmode; + int printnames; { - FILE *fout, *din = 0, *popen(); - int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)(); - int abortrecv(), is_retr, tcrflag, nfnd; char *bufp, *gunique(), msg; static char *buf; static int bufsize; + static char *buf; 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; if (is_retr && verbose && printnames) { @@ -671,10 +685,10 @@ recvrequest(cmd, local, remote, mode, printnames) oldintr = signal(SIGINT, abortrecv); if (strcmp(local, "-") && *local != '|') { if (access(local, 2) < 0) { - char *dir = rindex(local, '/'); + char *dir = strrchr(local, '/'); if (errno != ENOENT && errno != EACCES) { - perror(local); + warn("local: %s", local); (void) signal(SIGINT, oldintr); code = -1; return; @@ -685,14 +699,15 @@ recvrequest(cmd, local, remote, mode, printnames) if (dir != NULL) *dir = '/'; if (d < 0) { - perror(local); + warn("local: %s", local); (void) signal(SIGINT, oldintr); code = -1; return; } if (!runique && errno == EACCES && chmod(local, 0600) < 0) { - perror(local); + warn("local: %s", local); + (void) signal(SIGINT, oldintr); (void) signal(SIGINT, oldintr); code = -1; return; @@ -745,14 +760,14 @@ recvrequest(cmd, local, remote, mode, printnames) oldintp = signal(SIGPIPE, SIG_IGN); fout = popen(local + 1, "w"); if (fout == NULL) { - perror(local+1); + warn("%s", local+1); goto abort; } closefunc = pclose; } else { - fout = fopen(local, mode); + fout = fopen(local, lmode); if (fout == NULL) { - perror(local); + warn("local: %s", local); goto abort; } closefunc = fclose; @@ -762,9 +777,9 @@ recvrequest(cmd, local, remote, mode, printnames) 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"); + warn("malloc"); bufsize = 0; bufsize = 0; goto abort; @@ -797,7 +812,7 @@ recvrequest(cmd, local, remote, mode, printnames) } if (c < 0) { if (errno != EPIPE) - perror("netin"); + warn("netin"); bytes = -1; } if (d < c) { @@ -810,6 +825,8 @@ recvrequest(cmd, local, remote, mode, printnames) case TYPE_A: while ((c = getc(din)) != EOF) { + if (c == '\n') + bare_lfs++; while (c == '\r') { while (hash && (bytes >= hashbytes)) { (void) putchar('#'); @@ -837,6 +854,10 @@ recvrequest(cmd, local, remote, mode, printnames) 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('#'); @@ -845,11 +866,11 @@ break2: } if (ferror(din)) { if (errno != EPIPE) - perror("netin"); + warn("netin"); bytes = -1; } if (ferror(fout)) - perror(local); + warn("local: %s", local); break; } if (closefunc != NULL) @@ -870,47 +891,14 @@ abort: (void) gettimeofday(&stop, (struct timezone *)0); if (oldintp) (void) signal(SIGPIPE, oldintr); - (void) signal(SIGINT,SIG_IGN); + (void) signal(SIGINT, SIG_IGN); if (!cpend) { code = -1; - (void) signal(SIGINT,oldintr); + (void) signal(SIGINT, oldintr); 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); @@ -922,19 +910,17 @@ abort: (void) fclose(din); if (bytes > 0) ptransfer("received", bytes, &start, &stop); - (void) signal(SIGINT,oldintr); + (void) signal(SIGINT, oldintr); } /* - * Need to start a listen on the data channel - * before we send the command, otherwise the - * server's connect may fail. + * Need to start a listen on the data channel before we send the command, + * otherwise the server's connect may fail. */ -int sendport = -1; - +int initconn() { - register char *p, *a; + char *p, *a; int result, len, tmpno = 0; int on = 1; @@ -943,33 +929,33 @@ noport: 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"); + warn("socket"); if (tmpno) sendport = 1; return (1); } if (!sendport) if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) { - perror("ftp: setsockopt (reuse address)"); + warn("setsockopt (reuse address)"); goto bad; } if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) { - perror("ftp: bind"); + warn("bind"); goto bad; } if (options & SO_DEBUG && setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0) - perror("ftp: setsockopt (ignored)"); + warn("setsockopt (ignored)"); len = sizeof (data_addr); - if (getsockname(data, (char *)&data_addr, &len) < 0) { - perror("ftp: getsockname"); + if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) { + warn("getsockname"); goto bad; } if (listen(data, 1) < 0) - perror("ftp: listen"); + warn("listen"); if (sendport) { a = (char *)&data_addr.sin_addr; p = (char *)&data_addr.sin_port; @@ -987,6 +973,11 @@ noport: } if (tmpno) sendport = 1; +#ifdef IP_TOS + on = IPTOS_THROUGHPUT; + if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) + warn("setsockopt TOS (ignored)"); +#endif return (0); bad: (void) close(data), data = -1; @@ -996,23 +987,29 @@ bad: } FILE * -dataconn(mode) - char *mode; +dataconn(lmode) + char *lmode; { struct sockaddr_in from; - int s, fromlen = sizeof (from); + int s, fromlen = sizeof (from), tos; s = accept(data, (struct sockaddr *) &from, &fromlen); if (s < 0) { - perror("ftp: accept"); + warn("accept"); (void) close(data), data = -1; return (NULL); } (void) close(data); data = s; - return (fdopen(data, mode)); +#ifdef IP_TOS + tos = IPTOS_THROUGHPUT; + if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) + warn("setsockopt TOS (ignored)"); +#endif + return (fdopen(data, lmode)); } +void ptransfer(direction, bytes, t0, t1) char *direction; long bytes; @@ -1031,7 +1028,9 @@ ptransfer(direction, bytes, t0, t1) } } -/*tvadd(tsum, t0) +/* +void +tvadd(tsum, t0) struct timeval *tsum, *t0; { @@ -1039,8 +1038,10 @@ ptransfer(direction, bytes, t0, t1) tsum->tv_usec += t0->tv_usec; if (tsum->tv_usec > 1000000) tsum->tv_sec++, tsum->tv_usec -= 1000000; -} */ +} +*/ +void tvsub(tdiff, t1, t0) struct timeval *tdiff, *t1, *t0; { @@ -1051,18 +1052,18 @@ tvsub(tdiff, t1, t0) tdiff->tv_sec--, tdiff->tv_usec += 1000000; } +void psabort() { - extern int abrtflag; abrtflag++; } +void pswitch(flag) int flag; { - extern int proxy, abrtflag; - int (*oldintr)(); + sig_t oldintr; static struct comvars { int connect; char name[MAXHOSTNAMELEN]; @@ -1147,15 +1148,14 @@ pswitch(flag) (void) signal(SIGINT, oldintr); if (abrtflag) { abrtflag = 0; - (*oldintr)(); + (*oldintr)(SIGINT); } } -jmp_buf ptabort; -int ptabflg; - +void abortpt() { + printf("\n"); (void) fflush(stdout); ptabflg++; @@ -1164,11 +1164,12 @@ abortpt() longjmp(ptabort, 1); } +void proxtrans(cmd, local, remote) char *cmd, *local, *remote; { - int (*oldintr)(), abortpt(), prox_type, secndflag = 0, nfnd; - extern jmp_buf ptabort; + sig_t oldintr; + int secndflag = 0, prox_type, nfnd; char *cmd2; struct fd_set mask; @@ -1233,30 +1234,8 @@ abort: if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ if (command("%s %s", cmd2, local) != PRELIM) { pswitch(0); - 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) @@ -1264,58 +1243,14 @@ abort: (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); - 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; @@ -1323,37 +1258,15 @@ abort: 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); - if ((nfnd = empty(&mask,10)) <= 0) { + if ((nfnd = empty(&mask, 10)) <= 0) { if (nfnd < 0) { - perror("abort"); + warn("abort"); } if (ptabflg) code = -1; @@ -1370,7 +1283,10 @@ abort: (void) signal(SIGINT, oldintr); } -reset() +void +reset(argc, argv) + int argc; + char *argv[]; { struct fd_set mask; int nfnd = 1; @@ -1379,7 +1295,7 @@ reset() while (nfnd > 0) { FD_SET(fileno(cin), &mask); if ((nfnd = empty(&mask,0)) < 0) { - perror("reset"); + warn("reset"); code = -1; lostpeer(); } @@ -1394,7 +1310,7 @@ gunique(local) char *local; { static char new[MAXPATHLEN]; - char *cp = rindex(local, '/'); + char *cp = strrchr(local, '/'); int d, count=0; char ext = '1'; @@ -1404,8 +1320,8 @@ gunique(local) if (cp) *cp = '/'; if (d < 0) { - perror(local); - return((char *) 0); + warn("local: %s", local); + return ((char *) 0); } (void) strcpy(new, local); cp = new + strlen(new); @@ -1413,7 +1329,7 @@ gunique(local) while (!d) { if (++count == 100) { printf("runique: can't find unique file name.\n"); - return((char *) 0); + return ((char *) 0); } *cp++ = ext; *cp = '\0'; @@ -1432,5 +1348,46 @@ gunique(local) cp--; } } - return(new); + return (new); +} + +void +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) + warn("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) { + warn("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); }