libfetch-2.29:

Push \r\n up to the users of fetch_putln and remove it. Use send instead
of write(v) to avoid SIGPIPE.
This commit is contained in:
joerg 2010-01-23 14:25:26 +00:00
parent 1790f5afd6
commit 8efe5cbf9f
5 changed files with 54 additions and 111 deletions

View file

@ -1,7 +1,7 @@
# $NetBSD: Makefile,v 1.35 2010/01/22 13:21:09 joerg Exp $
# $NetBSD: Makefile,v 1.36 2010/01/23 14:25:26 joerg Exp $
#
DISTNAME= libfetch-2.28
DISTNAME= libfetch-2.29
CATEGORIES= net
MASTER_SITES= # empty
DISTFILES= # empty

View file

@ -1,4 +1,4 @@
/* $NetBSD: common.c,v 1.23 2010/01/23 13:39:42 joerg Exp $ */
/* $NetBSD: common.c,v 1.24 2010/01/23 14:25:26 joerg Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
* Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg@NetBSD.org>
@ -65,9 +65,6 @@
#include "fetch.h"
#include "common.h"
#define DECONST(x,y) ((x)(uintptr_t)(y))
/*** Local data **************************************************************/
/*
@ -83,10 +80,6 @@ static struct fetcherr netdb_errlist[] = {
{ -1, FETCH_UNKNOWN, "Unknown resolver error" }
};
/* End-of-Line */
static const char ENDL[2] = "\r\n";
/*** Error-reporting functions ***********************************************/
/*
@ -620,26 +613,12 @@ fetch_getln(conn_t *conn)
return (0);
}
/*
* Write to a connection w/ timeout
*/
ssize_t
fetch_write(conn_t *conn, const char *buf, size_t len)
{
struct iovec iov;
iov.iov_base = DECONST(char *, buf);
iov.iov_len = len;
return fetch_writev(conn, &iov, 1);
}
/*
* Write a vector to a connection w/ timeout
* Note: can modify the iovec.
*/
ssize_t
fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
fetch_write(conn_t *conn, const void *buf, size_t len)
{
struct timeval now, timeout, waittv;
fd_set writefds;
@ -653,7 +632,7 @@ fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
}
total = 0;
while (iovcnt > 0) {
while (len) {
while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) {
FD_SET(conn->sd, &writefds);
gettimeofday(&now, NULL);
@ -679,11 +658,10 @@ fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
errno = 0;
#ifdef WITH_SSL
if (conn->ssl != NULL)
wlen = SSL_write(conn->ssl,
iov->iov_base, iov->iov_len);
wlen = SSL_write(conn->ssl, buf, len);
else
#endif
wlen = writev(conn->sd, iov, iovcnt);
wlen = send(conn->sd, buf, len, MSG_NOSIGNAL);
if (wlen == 0) {
/* we consider a short write a failure */
errno = EPIPE;
@ -696,43 +674,13 @@ fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
return (-1);
}
total += wlen;
while (iovcnt > 0 && wlen >= (ssize_t)iov->iov_len) {
wlen -= iov->iov_len;
iov++;
iovcnt--;
}
if (iovcnt > 0) {
iov->iov_len -= wlen;
iov->iov_base = DECONST(char *, iov->iov_base) + wlen;
}
buf = (const char *)buf + wlen;
len -= wlen;
}
return (total);
}
/*
* Write a line of text to a connection w/ timeout
*/
int
fetch_putln(conn_t *conn, const char *str, size_t len)
{
struct iovec iov[2];
ssize_t ret;
iov[0].iov_base = DECONST(char *, str);
iov[0].iov_len = len;
iov[1].iov_base = DECONST(char *, ENDL);
iov[1].iov_len = sizeof(ENDL);
if (len == 0)
ret = fetch_writev(conn, &iov[1], 1);
else
ret = fetch_writev(conn, iov, 2);
if (ret == -1)
return (-1);
return (0);
}
/*
* Close connection
*/

View file

@ -1,4 +1,4 @@
/* $NetBSD: common.h,v 1.14 2010/01/23 13:39:42 joerg Exp $ */
/* $NetBSD: common.h,v 1.15 2010/01/23 14:25:26 joerg Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
* All rights reserved.
@ -86,9 +86,6 @@ struct fetcherr {
const char *string;
};
/* for fetch_writev */
struct iovec;
void fetch_seterr(struct fetcherr *, int);
void fetch_syserr(void);
void fetch_info(const char *, ...);
@ -102,9 +99,7 @@ conn_t *fetch_reopen(int);
int fetch_ssl(conn_t *, int);
ssize_t fetch_read(conn_t *, char *, size_t);
int fetch_getln(conn_t *);
ssize_t fetch_write(conn_t *, const char *, size_t);
ssize_t fetch_writev(conn_t *, struct iovec *, int);
int fetch_putln(conn_t *, const char *, size_t);
ssize_t fetch_write(conn_t *, const void *, size_t);
int fetch_close(conn_t *);
int fetch_add_entry(struct url_list *, struct url *, const char *, int);
int fetch_netrc_auth(struct url *url);

View file

@ -1,4 +1,4 @@
/* $NetBSD: ftp.c,v 1.33 2010/01/23 13:39:42 joerg Exp $ */
/* $NetBSD: ftp.c,v 1.34 2010/01/23 14:25:26 joerg Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
* Copyright (c) 2008, 2009, 2010 Joerg Sonnenberger <joerg@NetBSD.org>
@ -214,7 +214,7 @@ ftp_cmd(conn_t *conn, const char *fmt, ...)
return (-1);
}
r = fetch_putln(conn, msg, len);
r = fetch_write(conn, msg, len);
free(msg);
if (r == -1) {
@ -296,7 +296,7 @@ ftp_cwd(conn_t *conn, const char *file, int subdir)
end = file + strlen(file);
else if ((end = strrchr(file, '/')) == NULL)
return (0);
if ((e = ftp_cmd(conn, "PWD")) != FTP_WORKING_DIRECTORY ||
if ((e = ftp_cmd(conn, "PWD\r\n")) != FTP_WORKING_DIRECTORY ||
(e = ftp_pwd(conn, pwd, sizeof(pwd))) != FTP_OK) {
ftp_seterr(e);
return (-1);
@ -313,8 +313,8 @@ ftp_cwd(conn_t *conn, const char *file, int subdir)
break;
if (pwd[i] == '\0' && (file[i - 1] == '/' || file[i] == '/'))
break;
if ((e = ftp_cmd(conn, "CDUP")) != FTP_FILE_ACTION_OK ||
(e = ftp_cmd(conn, "PWD")) != FTP_WORKING_DIRECTORY ||
if ((e = ftp_cmd(conn, "CDUP\r\n")) != FTP_FILE_ACTION_OK ||
(e = ftp_cmd(conn, "PWD\r\n")) != FTP_WORKING_DIRECTORY ||
(e = ftp_pwd(conn, pwd, sizeof(pwd))) != FTP_OK) {
ftp_seterr(e);
return (-1);
@ -331,7 +331,7 @@ ftp_cwd(conn_t *conn, const char *file, int subdir)
return (0);
/* Change to the directory all in one chunk (e.g., foo/bar/baz). */
e = ftp_cmd(conn, "CWD %.*s", (int)(end - beg), beg);
e = ftp_cmd(conn, "CWD %.*s\r\n", (int)(end - beg), beg);
if (e == FTP_FILE_ACTION_OK)
return (0);
#endif /* FTP_COMBINE_CWDS */
@ -342,7 +342,7 @@ ftp_cwd(conn_t *conn, const char *file, int subdir)
++beg, ++i;
for (++i; file + i < end && file[i] != '/'; ++i)
/* nothing */ ;
e = ftp_cmd(conn, "CWD %.*s", file + i - beg, beg);
e = ftp_cmd(conn, "CWD %.*s\r\n", file + i - beg, beg);
if (e != FTP_FILE_ACTION_OK) {
ftp_seterr(e);
return (-1);
@ -368,7 +368,7 @@ ftp_mode_type(conn_t *conn, int mode, int type)
default:
return (FTP_PROTOCOL_ERROR);
}
if ((e = ftp_cmd(conn, "MODE %c", mode)) != FTP_OK) {
if ((e = ftp_cmd(conn, "MODE %c\r\n", mode)) != FTP_OK) {
if (mode == 'S') {
/*
* Stream mode is supposed to be the default - so
@ -404,7 +404,7 @@ ftp_mode_type(conn_t *conn, int mode, int type)
default:
return (FTP_PROTOCOL_ERROR);
}
if ((e = ftp_cmd(conn, "TYPE %c", type)) != FTP_OK)
if ((e = ftp_cmd(conn, "TYPE %c\r\n", type)) != FTP_OK)
return (e);
return (FTP_OK);
@ -433,7 +433,7 @@ ftp_stat(conn_t *conn, const char *file, struct url_stat *us)
return (-1);
}
e = ftp_cmd(conn, "SIZE %.*s", filenamelen, filename);
e = ftp_cmd(conn, "SIZE %.*s\r\n", filenamelen, filename);
if (e != FTP_FILE_STATUS) {
ftp_seterr(e);
return (-1);
@ -450,7 +450,7 @@ ftp_stat(conn_t *conn, const char *file, struct url_stat *us)
if (us->size == 0)
us->size = -1;
e = ftp_cmd(conn, "MDTM %.*s", filenamelen, filename);
e = ftp_cmd(conn, "MDTM %.*s\r\n", filenamelen, filename);
if (e != FTP_FILE_STATUS) {
ftp_seterr(e);
return (-1);
@ -565,7 +565,7 @@ ftp_writefn(void *v, const void *buf, size_t len)
static int
ftp_disconnect(conn_t *conn)
{
ftp_cmd(conn, "QUIT");
ftp_cmd(conn, "QUIT\r\n");
return fetch_close(conn);
}
@ -680,14 +680,14 @@ retry_mode:
fetch_info("setting passive mode");
switch (u.ss.ss_family) {
case AF_INET:
if ((e = ftp_cmd(conn, "PASV")) != FTP_PASSIVE_MODE)
if ((e = ftp_cmd(conn, "PASV\r\n")) != FTP_PASSIVE_MODE)
goto ouch;
break;
case AF_INET6:
if ((e = ftp_cmd(conn, "EPSV")) != FTP_EPASSIVE_MODE) {
if ((e = ftp_cmd(conn, "EPSV\r\n")) != FTP_EPASSIVE_MODE) {
if (e == -1)
goto ouch;
if ((e = ftp_cmd(conn, "LPSV")) !=
if ((e = ftp_cmd(conn, "LPSV\r\n")) !=
FTP_LPASSIVE_MODE)
goto ouch;
}
@ -747,7 +747,7 @@ retry_mode:
/* seek to required offset */
if (offset)
if (ftp_cmd(conn, "REST %lu", (unsigned long)offset) != FTP_FILE_OK)
if (ftp_cmd(conn, "REST %lu\r\n", (unsigned long)offset) != FTP_FILE_OK)
goto sysouch;
/* construct sockaddr for data socket */
@ -792,9 +792,9 @@ retry_mode:
if (verbose)
fetch_info("initiating transfer");
if (op_arg)
e = ftp_cmd(conn, "%s%s%s", oper, *op_arg ? " " : "", op_arg);
e = ftp_cmd(conn, "%s%s%s\r\n", oper, *op_arg ? " " : "", op_arg);
else
e = ftp_cmd(conn, "%s %.*s", oper,
e = ftp_cmd(conn, "%s %.*s\r\n", oper,
filenamelen, filename);
if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION)
goto ouch;
@ -843,7 +843,7 @@ retry_mode:
case AF_INET:
a = ntohl(u.sin4.sin_addr.s_addr);
p = ntohs(u.sin4.sin_port);
e = ftp_cmd(conn, "PORT %d,%d,%d,%d,%d,%d",
e = ftp_cmd(conn, "PORT %d,%d,%d,%d,%d,%d\r\n",
(a >> 24) & 0xff, (a >> 16) & 0xff,
(a >> 8) & 0xff, a & 0xff,
(p >> 8) & 0xff, p & 0xff);
@ -855,7 +855,7 @@ retry_mode:
if (getnameinfo(&u.sa, l,
hname, sizeof(hname),
NULL, 0, NI_NUMERICHOST) == 0) {
e = ftp_cmd(conn, "EPRT |%d|%s|%d|", 2, hname,
e = ftp_cmd(conn, "EPRT |%d|%s|%d|\r\n", 2, hname,
htons(u.sin6.sin6_port));
if (e == -1)
goto ouch;
@ -863,7 +863,7 @@ retry_mode:
if (e != FTP_OK) {
ap = (char *)&u.sin6.sin6_addr;
e = ftp_cmd(conn,
"LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
"LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",
6, 16,
UC(ap[0]), UC(ap[1]), UC(ap[2]), UC(ap[3]),
UC(ap[4]), UC(ap[5]), UC(ap[6]), UC(ap[7]),
@ -883,16 +883,16 @@ retry_mode:
/* seek to required offset */
if (offset)
if (ftp_cmd(conn, "REST %llu", (unsigned long long)offset) != FTP_FILE_OK)
if (ftp_cmd(conn, "REST %llu\r\n", (unsigned long long)offset) != FTP_FILE_OK)
goto sysouch;
/* make the server initiate the transfer */
if (verbose)
fetch_info("initiating transfer");
if (op_arg)
e = ftp_cmd(conn, "%s%s%s", oper, *op_arg ? " " : "", op_arg);
e = ftp_cmd(conn, "%s%s%s\r\n", oper, *op_arg ? " " : "", op_arg);
else
e = ftp_cmd(conn, "%s %.*s", oper,
e = ftp_cmd(conn, "%s %.*s\r\n", oper,
filenamelen, filename);
if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION)
goto ouch;
@ -943,11 +943,11 @@ ftp_authenticate(conn_t *conn, struct url *url, struct url *purl)
if (user == NULL || *user == '\0')
user = FTP_ANONYMOUS_USER;
if (purl && url->port == fetch_default_port(url->scheme))
e = ftp_cmd(conn, "USER %s@%s", user, url->host);
e = ftp_cmd(conn, "USER %s@%s\r\n", user, url->host);
else if (purl)
e = ftp_cmd(conn, "USER %s@%s@%d", user, url->host, url->port);
e = ftp_cmd(conn, "USER %s@%s@%d\r\n", user, url->host, url->port);
else
e = ftp_cmd(conn, "USER %s", user);
e = ftp_cmd(conn, "USER %s\r\n", user);
/* did the server request a password? */
if (e == FTP_NEED_PASSWORD) {
@ -966,7 +966,7 @@ ftp_authenticate(conn_t *conn, struct url *url, struct url *purl)
pbuf[sizeof(pbuf) - 1] = '\0';
pwd = pbuf;
}
e = ftp_cmd(conn, "PASS %s", pwd);
e = ftp_cmd(conn, "PASS %s\r\n", pwd);
}
return (e);
@ -1010,7 +1010,7 @@ ftp_connect(struct url *url, struct url *purl, const char *flags)
url->port = fetch_default_port(url->scheme);
while ((conn = fetch_cache_get(url, af)) != NULL) {
e = ftp_cmd(conn, "NOOP");
e = ftp_cmd(conn, "NOOP\r\n");
if (e == FTP_OK)
return conn;
fetch_close(conn);

View file

@ -1,4 +1,4 @@
/* $NetBSD: http.c,v 1.26 2010/01/22 13:21:09 joerg Exp $ */
/* $NetBSD: http.c,v 1.27 2010/01/23 14:25:26 joerg Exp $ */
/*-
* Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav
* Copyright (c) 2003 Thomas Klausner <wiz@NetBSD.org>
@ -393,7 +393,7 @@ http_cmd(conn_t *conn, const char *fmt, ...)
return (-1);
}
r = fetch_putln(conn, msg, len);
r = fetch_write(conn, msg, len);
free(msg);
if (r == -1) {
@ -634,7 +634,7 @@ http_basic_auth(conn_t *conn, const char *hdr, const char *usr, const char *pwd)
free(upw);
if (auth == NULL)
return (-1);
r = http_cmd(conn, "%s: Basic %s", hdr, auth);
r = http_cmd(conn, "%s: Basic %s\r\n", hdr, auth);
free(auth);
return (r);
}
@ -764,7 +764,7 @@ set_if_modified_since(conn_t *conn, time_t last_modified)
snprintf(buf, sizeof(buf), "%.3s, %02d %.3s %4d %02d:%02d:%02d GMT",
weekdays + tm.tm_wday * 3, tm.tm_mday, months + tm.tm_mon * 3,
tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
http_cmd(conn, "If-Modified-Since: %s", buf);
http_cmd(conn, "If-Modified-Since: %s\r\n", buf);
}
@ -858,10 +858,10 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
fetch_info("requesting %s://%s%s",
url->scheme, host, url->doc);
if (purl) {
http_cmd(conn, "%s %s://%s%s HTTP/1.1",
http_cmd(conn, "%s %s://%s%s HTTP/1.1\r\n",
op, url->scheme, host, url->doc);
} else {
http_cmd(conn, "%s %s HTTP/1.1",
http_cmd(conn, "%s %s HTTP/1.1\r\n",
op, url->doc);
}
@ -869,7 +869,7 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
set_if_modified_since(conn, url->last_modified);
/* virtual host */
http_cmd(conn, "Host: %s", host);
http_cmd(conn, "Host: %s\r\n", host);
/* proxy authorization */
if (purl) {
@ -897,19 +897,19 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
/* other headers */
if ((p = getenv("HTTP_REFERER")) != NULL && *p != '\0') {
if (strcasecmp(p, "auto") == 0)
http_cmd(conn, "Referer: %s://%s%s",
http_cmd(conn, "Referer: %s://%s%s\r\n",
url->scheme, host, url->doc);
else
http_cmd(conn, "Referer: %s", p);
http_cmd(conn, "Referer: %s\r\n", p);
}
if ((p = getenv("HTTP_USER_AGENT")) != NULL && *p != '\0')
http_cmd(conn, "User-Agent: %s", p);
http_cmd(conn, "User-Agent: %s\r\n", p);
else
http_cmd(conn, "User-Agent: %s ", _LIBFETCH_VER);
http_cmd(conn, "User-Agent: %s\r\n", _LIBFETCH_VER);
if (url->offset > 0)
http_cmd(conn, "Range: bytes=%lld-", (long long)url->offset);
http_cmd(conn, "Connection: close");
http_cmd(conn, "");
http_cmd(conn, "Range: bytes=%lld-\r\n", (long long)url->offset);
http_cmd(conn, "Connection: close\r\n");
http_cmd(conn, "\r\n");
/*
* Force the queued request to be dispatched. Normally, one