Page MenuHomeFreeBSD

D57907.id180818.diff
No OneTemporary

D57907.id180818.diff

diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h
--- a/lib/libfetch/common.h
+++ b/lib/libfetch/common.h
@@ -51,6 +51,7 @@
char *buf; /* buffer */
size_t bufsize; /* buffer size */
size_t buflen; /* length of buffer contents */
+ size_t pos; /* current position in buffer */
int err; /* last protocol reply code */
#ifdef WITH_SSL
SSL *ssl; /* SSL handle */
@@ -120,7 +121,7 @@
#endif
int fetch_ssl(conn_t *, const struct url *, int);
ssize_t fetch_read(conn_t *, char *, size_t);
-int fetch_getln(conn_t *);
+ssize_t 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);
diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c
--- a/lib/libfetch/common.c
+++ b/lib/libfetch/common.c
@@ -1402,47 +1402,74 @@
*/
#define MIN_BUF_SIZE 1024
-int
+ssize_t
fetch_getln(conn_t *conn)
{
char *tmp;
size_t tmpsize;
- ssize_t len;
- char c;
+ ssize_t rlen;
+ /* allocate initial buffer */
if (conn->buf == NULL) {
- if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL) {
- errno = ENOMEM;
+ if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL)
return (-1);
- }
conn->bufsize = MIN_BUF_SIZE;
+ conn->buflen = 0;
+ conn->pos = 0;
}
- conn->buf[0] = '\0';
- conn->buflen = 0;
+ /* move residual data up */
+ if (conn->buflen > 0) {
+ if (conn->pos < conn->buflen) {
+ memmove(conn->buf, conn->buf + conn->pos,
+ conn->buflen - conn->pos);
+ }
+ conn->buflen -= conn->pos;
+ conn->pos -= conn->pos;
+ }
- do {
- len = fetch_read(conn, &c, 1);
- if (len == -1)
+ /* do we have a complete line? */
+ while (conn->pos < conn->buflen)
+ if (conn->buf[conn->pos++] == '\n')
+ goto found;
+
+ for (;;) {
+ /* read as much as we can right now */
+ rlen = fetch_read(conn, conn->buf + conn->buflen,
+ conn->bufsize - conn->buflen - 1);
+ /* error */
+ if (rlen < 0)
return (-1);
- if (len == 0)
+ /* advance and terminate */
+ conn->buflen += rlen;
+ conn->buf[conn->buflen] = '\0';
+ /* connection closed */
+ if (rlen == 0)
break;
- conn->buf[conn->buflen++] = c;
- if (conn->buflen == conn->bufsize) {
+ /* look for a newline */
+ while (conn->pos < conn->buflen)
+ if (conn->buf[conn->pos++] == '\n')
+ goto found;
+ /* do we need a bigger buffer? */
+ if (conn->buflen > conn->bufsize / 2) {
tmp = conn->buf;
- tmpsize = conn->bufsize * 2 + 1;
- if ((tmp = realloc(tmp, tmpsize)) == NULL) {
- errno = ENOMEM;
+ tmpsize = conn->bufsize * 2;
+ if ((tmp = realloc(tmp, tmpsize)) == NULL)
return (-1);
- }
conn->buf = tmp;
conn->bufsize = tmpsize;
}
- } while (c != '\n');
-
- conn->buf[conn->buflen] = '\0';
- DEBUGF("<<< %s", conn->buf);
- return (0);
+ }
+ /* connection closed, return what's left */
+ conn->pos = conn->buflen;
+found:
+ rlen = conn->pos;
+ if (rlen > 0 && conn->buf[rlen - 1] == '\n')
+ conn->buf[--rlen] = '\0';
+ if (rlen > 0 && conn->buf[rlen - 1] == '\r')
+ conn->buf[--rlen] = '\0';
+ DEBUGF("<<< %.*s\n", (int)rlen, conn->buf);
+ return (rlen);
}
diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c
--- a/lib/libfetch/ftp.c
+++ b/lib/libfetch/ftp.c
@@ -142,24 +142,21 @@
static int
ftp_chkerr(conn_t *conn)
{
- if (fetch_getln(conn) == -1) {
+ ssize_t rlen;
+
+ if ((rlen = fetch_getln(conn)) < 0) {
fetch_syserr();
return (-1);
}
if (isftpinfo(conn->buf)) {
while (conn->buflen && !isftpreply(conn->buf)) {
- if (fetch_getln(conn) == -1) {
+ if ((rlen = fetch_getln(conn)) < 0) {
fetch_syserr();
return (-1);
}
}
}
- while (conn->buflen &&
- isspace((unsigned char)conn->buf[conn->buflen - 1]))
- conn->buflen--;
- conn->buf[conn->buflen] = '\0';
-
if (!isftpreply(conn->buf)) {
ftp_seterr(FTP_PROTOCOL_ERROR);
return (-1);

File Metadata

Mime Type
text/plain
Expires
Mon, Jul 6, 7:07 PM (9 h, 12 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34765805
Default Alt Text
D57907.id180818.diff (3 KB)

Event Timeline