diff options
author | jkh <jkh@FreeBSD.org> | 1997-01-17 12:51:55 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1997-01-17 12:51:55 +0000 |
commit | c84c52a34f4d8aba20ad7a11c90ebdb3c442e1f8 (patch) | |
tree | 366e8075293f2b7d325dc51448809d5ec6996796 /lib | |
parent | dc311d3ebe8d1fd57546c7979f7f22ec79caac4b (diff) | |
download | FreeBSD-src-c84c52a34f4d8aba20ad7a11c90ebdb3c442e1f8.zip FreeBSD-src-c84c52a34f4d8aba20ad7a11c90ebdb3c442e1f8.tar.gz |
Yow! Is my face red... I just noticed (duh) that signal() always installs
the handler with SA_RESTART set, so the system calls I wanted to have the
timeout effect will just restart instead (which is NOT what I wanted).
Sheepishly use sigaction() like a good boy and make timeouts actually do
something.
Also pass errors out more effectively so that fetch(1) actually understands
what went wrong.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libftpio/ftpio.c | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/lib/libftpio/ftpio.c b/lib/libftpio/ftpio.c index a8da073..b82efaf 100644 --- a/lib/libftpio/ftpio.c +++ b/lib/libftpio/ftpio.c @@ -180,6 +180,8 @@ ftpErrString(int errno) { int k; + if (errno == -1) + return("connection in wrong state"); for (k = 0; k < ftpErrListLength; k++) if (ftpErrList[k].num == errno) return(ftpErrList[k].string); @@ -276,8 +278,24 @@ ftpLogin(char *host, char *user, char *passwd, int port, int verbose, int *retco fp = funopen(n, ftp_read_method, ftp_write_method, NULL, ftp_close_method); /* BSD 4.4 function! */ fp->_file = n->fd_ctrl; } - if (n && retcode) - *retcode = n->errno; + if (retcode) { + if (!n) + *retcode = (FtpTimedOut ? FTP_TIMED_OUT : -1); + /* Poor attempt at mapping real errnos to FTP error codes */ + else switch(n->errno) { + case EADDRNOTAVAIL: + *retcode = FTP_TIMED_OUT; /* Actually no such host, but we have no way of saying that. :-( */ + break; + + case ETIMEDOUT: + *retcode = FTP_TIMED_OUT; + break; + + default: + *retcode = n->errno; + break; + } + } return fp; } @@ -486,6 +504,8 @@ ftp_timeout(int sig) /* Debug("ftp_pkg: ftp_timeout called - operation timed out"); */ } +static struct sigaction new; + static void ftp_set_timeout(void) { @@ -493,8 +513,9 @@ ftp_set_timeout(void) int ival; FtpTimedOut = FALSE; - signal(SIGALRM, ftp_timeout); - cp = getenv("FTP_TIMEOUT_INTERVAL"); + new.sa_handler = ftp_timeout; + sigaction(SIGALRM, &new, NULL); + cp = getenv("FTP_TIMEOUT"); if (!cp || !(ival = atoi(cp))) ival = 120; alarm(ival); @@ -504,7 +525,8 @@ static void ftp_clear_timeout(void) { alarm(0); - signal(SIGALRM, SIG_DFL); + new.sa_handler = SIG_DFL; + sigaction(SIGALRM, &new, NULL); } static int @@ -651,6 +673,7 @@ ftp_login_session(FTP_t ftp, char *host, char *user, char *passwd, int port, int if (ftp->con_state != init) { ftp_close(ftp); + ftp->errno = -1; return FAILURE; } @@ -670,19 +693,24 @@ ftp_login_session(FTP_t ftp, char *host, char *user, char *passwd, int port, int } else { he = gethostbyname(host); - if (!he) + if (!he) { + ftp->errno = 0; return FAILURE; + } ftp->addrtype = sin.sin_family = he->h_addrtype; bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length); } sin.sin_port = htons(port); - if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) + if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) { + ftp->errno = -1; return FAILURE; + } if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { (void)close(s); + ftp->errno = errno; return FAILURE; } @@ -718,15 +746,19 @@ ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, off_t if (ftp->con_state != isopen) return botch("ftp_file_op", "open"); - if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) + if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) { + ftp->errno = errno; return FAILURE; + } if (ftp->is_passive) { if (ftp->is_verbose) fprintf(stderr, "Sending PASV\n"); if (writes(ftp->fd_ctrl, "PASV\r\n")) { ftp_close(ftp); - return FAILURE; + if (FtpTimedOut) + ftp->errno = FTP_TIMED_OUT; + return FTP_TIMED_OUT; } i = get_a_number(ftp, &q); if (check_code(ftp, i, FTP_PASSIVE_HAPPY)) { |