Import and merge libfetch-2.31 from NetBSD pkgsrc.
This commit is contained in:
parent
0c67681ce1
commit
bd37736d89
5
3RDPARTY
5
3RDPARTY
@ -2,9 +2,6 @@ XBPS includes the following software from third parties for
|
|||||||
internal use in the code:
|
internal use in the code:
|
||||||
|
|
||||||
- pkgmatch code from FreeBSD.
|
- pkgmatch code from FreeBSD.
|
||||||
|
|
||||||
- strlcat and strlcpy functions from OpenBSD.
|
- strlcat and strlcpy functions from OpenBSD.
|
||||||
|
- libfetch-2.31 from NetBSD.
|
||||||
- libfetch-2.30 from NetBSD.
|
|
||||||
|
|
||||||
- portableproplib-0.4.1 from http://code.google.com/p/portableproplib
|
- portableproplib-0.4.1 from http://code.google.com/p/portableproplib
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: common.c,v 1.24 2010/01/23 14:25:26 joerg Exp $ */
|
/* $NetBSD: common.c,v 1.26 2010/03/21 16:48:43 joerg Exp $ */
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
||||||
* Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg@NetBSD.org>
|
* Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg@NetBSD.org>
|
||||||
@ -62,6 +62,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifndef MSG_NOSIGNAL
|
||||||
|
#include <signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "fetch.h"
|
#include "fetch.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
@ -227,6 +231,7 @@ fetch_reopen(int sd)
|
|||||||
/* allocate and fill connection structure */
|
/* allocate and fill connection structure */
|
||||||
if ((conn = calloc(1, sizeof(*conn))) == NULL)
|
if ((conn = calloc(1, sizeof(*conn))) == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
conn->ftp_home = NULL;
|
||||||
conn->cache_url = NULL;
|
conn->cache_url = NULL;
|
||||||
conn->next_buf = NULL;
|
conn->next_buf = NULL;
|
||||||
conn->next_len = 0;
|
conn->next_len = 0;
|
||||||
@ -624,6 +629,17 @@ fetch_write(conn_t *conn, const void *buf, size_t len)
|
|||||||
fd_set writefds;
|
fd_set writefds;
|
||||||
ssize_t wlen, total;
|
ssize_t wlen, total;
|
||||||
int r;
|
int r;
|
||||||
|
#ifndef MSG_NOSIGNAL
|
||||||
|
static int killed_sigpipe;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MSG_NOSIGNAL
|
||||||
|
if (!killed_sigpipe) {
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
killed_sigpipe = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (fetchTimeout) {
|
if (fetchTimeout) {
|
||||||
FD_ZERO(&writefds);
|
FD_ZERO(&writefds);
|
||||||
@ -661,7 +677,11 @@ fetch_write(conn_t *conn, const void *buf, size_t len)
|
|||||||
wlen = SSL_write(conn->ssl, buf, len);
|
wlen = SSL_write(conn->ssl, buf, len);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MSG_NOSIGNAL
|
||||||
|
wlen = send(conn->sd, buf, len, 0);
|
||||||
|
#else
|
||||||
wlen = send(conn->sd, buf, len, MSG_NOSIGNAL);
|
wlen = send(conn->sd, buf, len, MSG_NOSIGNAL);
|
||||||
|
#endif
|
||||||
if (wlen == 0) {
|
if (wlen == 0) {
|
||||||
/* we consider a short write a failure */
|
/* we consider a short write a failure */
|
||||||
errno = EPIPE;
|
errno = EPIPE;
|
||||||
@ -692,6 +712,7 @@ fetch_close(conn_t *conn)
|
|||||||
ret = close(conn->sd);
|
ret = close(conn->sd);
|
||||||
if (conn->cache_url)
|
if (conn->cache_url)
|
||||||
fetchFreeURL(conn->cache_url);
|
fetchFreeURL(conn->cache_url);
|
||||||
|
free(conn->ftp_home);
|
||||||
free(conn->buf);
|
free(conn->buf);
|
||||||
free(conn);
|
free(conn);
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: common.h,v 1.15 2010/01/23 14:25:26 joerg Exp $ */
|
/* $NetBSD: common.h,v 1.16 2010/03/21 16:48:43 joerg Exp $ */
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -73,6 +73,8 @@ struct fetchconn {
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char *ftp_home;
|
||||||
|
|
||||||
struct url *cache_url;
|
struct url *cache_url;
|
||||||
int cache_af;
|
int cache_af;
|
||||||
int (*cache_close)(conn_t *);
|
int (*cache_close)(conn_t *);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: ftp.c,v 1.34 2010/01/23 14:25:26 joerg Exp $ */
|
/* $NetBSD: ftp.c,v 1.35 2010/03/21 16:48:43 joerg Exp $ */
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
||||||
* Copyright (c) 2008, 2009, 2010 Joerg Sonnenberger <joerg@NetBSD.org>
|
* Copyright (c) 2008, 2009, 2010 Joerg Sonnenberger <joerg@NetBSD.org>
|
||||||
@ -247,7 +247,7 @@ ftp_filename(const char *file, int *len, int *type, int subdir)
|
|||||||
* command.
|
* command.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ftp_pwd(conn_t *conn, char *pwd, size_t pwdlen)
|
ftp_pwd(conn_t *conn, char **pwd)
|
||||||
{
|
{
|
||||||
char *src, *dst, *end;
|
char *src, *dst, *end;
|
||||||
int q;
|
int q;
|
||||||
@ -259,7 +259,10 @@ ftp_pwd(conn_t *conn, char *pwd, size_t pwdlen)
|
|||||||
src = conn->buf + 4;
|
src = conn->buf + 4;
|
||||||
if (src >= end || *src++ != '"')
|
if (src >= end || *src++ != '"')
|
||||||
return (FTP_PROTOCOL_ERROR);
|
return (FTP_PROTOCOL_ERROR);
|
||||||
for (q = 0, dst = pwd; src < end && pwdlen--; ++src) {
|
*pwd = malloc(end - src + 1);
|
||||||
|
if (*pwd == NULL)
|
||||||
|
return (FTP_PROTOCOL_ERROR);
|
||||||
|
for (q = 0, dst = *pwd; src < end; ++src) {
|
||||||
if (!q && *src == '"')
|
if (!q && *src == '"')
|
||||||
q = 1;
|
q = 1;
|
||||||
else if (q && *src != '"')
|
else if (q && *src != '"')
|
||||||
@ -269,9 +272,12 @@ ftp_pwd(conn_t *conn, char *pwd, size_t pwdlen)
|
|||||||
else
|
else
|
||||||
*dst++ = *src;
|
*dst++ = *src;
|
||||||
}
|
}
|
||||||
if (!pwdlen)
|
|
||||||
return (FTP_PROTOCOL_ERROR);
|
|
||||||
*dst = '\0';
|
*dst = '\0';
|
||||||
|
if (**pwd != '/') {
|
||||||
|
free(*pwd);
|
||||||
|
*pwd = NULL;
|
||||||
|
return (FTP_PROTOCOL_ERROR);
|
||||||
|
}
|
||||||
return (FTP_OK);
|
return (FTP_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,69 +286,109 @@ ftp_pwd(conn_t *conn, char *pwd, size_t pwdlen)
|
|||||||
* file.
|
* file.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ftp_cwd(conn_t *conn, const char *file, int subdir)
|
ftp_cwd(conn_t *conn, const char *path, int subdir)
|
||||||
{
|
{
|
||||||
const char *beg, *end;
|
const char *beg, *end;
|
||||||
char pwd[PATH_MAX];
|
char *pwd, *dst;
|
||||||
int e, i, len;
|
int e, i, len;
|
||||||
|
|
||||||
/* If no slashes in name, no need to change dirs. */
|
if (*path != '/') {
|
||||||
if (subdir)
|
ftp_seterr(501);
|
||||||
end = file + strlen(file);
|
return (-1);
|
||||||
else if ((end = strrchr(file, '/')) == NULL)
|
}
|
||||||
return (0);
|
++path;
|
||||||
|
|
||||||
|
/* Simple case: still in the home directory and no directory change. */
|
||||||
|
if (conn->ftp_home == NULL && strchr(path, '/') == NULL &&
|
||||||
|
(!subdir || *path == '\0'))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if ((e = ftp_cmd(conn, "PWD\r\n")) != FTP_WORKING_DIRECTORY ||
|
if ((e = ftp_cmd(conn, "PWD\r\n")) != FTP_WORKING_DIRECTORY ||
|
||||||
(e = ftp_pwd(conn, pwd, sizeof(pwd))) != FTP_OK) {
|
(e = ftp_pwd(conn, &pwd)) != FTP_OK) {
|
||||||
ftp_seterr(e);
|
ftp_seterr(e);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
if (conn->ftp_home == NULL && (conn->ftp_home = strdup(pwd)) == NULL) {
|
||||||
|
fetch_syserr();
|
||||||
|
free(pwd);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (*path == '/') {
|
||||||
|
while (path[1] == '/')
|
||||||
|
++path;
|
||||||
|
dst = strdup(path);
|
||||||
|
} else if (strcmp(conn->ftp_home, "/") == 0) {
|
||||||
|
dst = strdup(path - 1);
|
||||||
|
} else {
|
||||||
|
asprintf(&dst, "%s/%s", conn->ftp_home, path);
|
||||||
|
}
|
||||||
|
if (dst == NULL) {
|
||||||
|
fetch_syserr();
|
||||||
|
free(pwd);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subdir)
|
||||||
|
end = dst + strlen(dst);
|
||||||
|
else
|
||||||
|
end = strrchr(dst, '/');
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
len = strlen(pwd);
|
len = strlen(pwd);
|
||||||
|
|
||||||
/* Look for a common prefix between PWD and dir to fetch. */
|
/* Look for a common prefix between PWD and dir to fetch. */
|
||||||
for (i = 0; i <= len && i <= end - file; ++i)
|
for (i = 0; i <= len && i <= end - dst; ++i)
|
||||||
if (pwd[i] != file[i])
|
if (pwd[i] != dst[i])
|
||||||
break;
|
break;
|
||||||
/* Keep going up a dir until we have a matching prefix. */
|
/* Keep going up a dir until we have a matching prefix. */
|
||||||
if (strcmp(pwd, "/") == 0)
|
if (strcmp(pwd, "/") == 0)
|
||||||
break;
|
break;
|
||||||
if (pwd[i] == '\0' && (file[i - 1] == '/' || file[i] == '/'))
|
if (pwd[i] == '\0' && (dst[i - 1] == '/' || dst[i] == '/'))
|
||||||
break;
|
break;
|
||||||
|
free(pwd);
|
||||||
if ((e = ftp_cmd(conn, "CDUP\r\n")) != FTP_FILE_ACTION_OK ||
|
if ((e = ftp_cmd(conn, "CDUP\r\n")) != FTP_FILE_ACTION_OK ||
|
||||||
(e = ftp_cmd(conn, "PWD\r\n")) != FTP_WORKING_DIRECTORY ||
|
(e = ftp_cmd(conn, "PWD\r\n")) != FTP_WORKING_DIRECTORY ||
|
||||||
(e = ftp_pwd(conn, pwd, sizeof(pwd))) != FTP_OK) {
|
(e = ftp_pwd(conn, &pwd)) != FTP_OK) {
|
||||||
ftp_seterr(e);
|
ftp_seterr(e);
|
||||||
|
free(dst);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(pwd);
|
||||||
|
|
||||||
#ifdef FTP_COMBINE_CWDS
|
#ifdef FTP_COMBINE_CWDS
|
||||||
/* Skip leading slashes, even "////". */
|
/* Skip leading slashes, even "////". */
|
||||||
for (beg = file + i; beg < end && *beg == '/'; ++beg, ++i)
|
for (beg = dst + i; beg < end && *beg == '/'; ++beg, ++i)
|
||||||
/* nothing */ ;
|
/* nothing */ ;
|
||||||
|
|
||||||
/* If there is no trailing dir, we're already there. */
|
/* If there is no trailing dir, we're already there. */
|
||||||
if (beg >= end)
|
if (beg >= end) {
|
||||||
|
free(dst);
|
||||||
return (0);
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Change to the directory all in one chunk (e.g., foo/bar/baz). */
|
/* Change to the directory all in one chunk (e.g., foo/bar/baz). */
|
||||||
e = ftp_cmd(conn, "CWD %.*s\r\n", (int)(end - beg), beg);
|
e = ftp_cmd(conn, "CWD %.*s\r\n", (int)(end - beg), beg);
|
||||||
if (e == FTP_FILE_ACTION_OK)
|
if (e == FTP_FILE_ACTION_OK) {
|
||||||
|
free(dst);
|
||||||
return (0);
|
return (0);
|
||||||
|
}
|
||||||
#endif /* FTP_COMBINE_CWDS */
|
#endif /* FTP_COMBINE_CWDS */
|
||||||
|
|
||||||
/* That didn't work so go back to legacy behavior (multiple CWDs). */
|
/* That didn't work so go back to legacy behavior (multiple CWDs). */
|
||||||
for (beg = file + i; beg < end; beg = file + i + 1) {
|
for (beg = dst + i; beg < end; beg = dst + i + 1) {
|
||||||
while (*beg == '/')
|
while (*beg == '/')
|
||||||
++beg, ++i;
|
++beg, ++i;
|
||||||
for (++i; file + i < end && file[i] != '/'; ++i)
|
for (++i; dst + i < end && dst[i] != '/'; ++i)
|
||||||
/* nothing */ ;
|
/* nothing */ ;
|
||||||
e = ftp_cmd(conn, "CWD %.*s\r\n", file + i - beg, beg);
|
e = ftp_cmd(conn, "CWD %.*s\r\n", dst + i - beg, beg);
|
||||||
if (e != FTP_FILE_ACTION_OK) {
|
if (e != FTP_FILE_ACTION_OK) {
|
||||||
|
free(dst);
|
||||||
ftp_seterr(e);
|
ftp_seterr(e);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(dst);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user