From 510c84d3bbfd29a27c90023d6379df194799bf7c Mon Sep 17 00:00:00 2001 From: Juan RP Date: Sun, 29 Jun 2014 10:29:36 +0200 Subject: [PATCH] libfetch: synchronized with NetBSD's pkgsrc/libfetch, preserving our changes. --- NEWS | 2 ++ lib/Makefile | 2 +- lib/fetch/common.c | 3 +- lib/fetch/common.h | 13 +++++++-- lib/fetch/fetch.c | 1 + lib/fetch/ftp.c | 68 ++++++++++++++++++++++++++++------------------ lib/fetch/http.c | 30 ++++++++++---------- 7 files changed, 72 insertions(+), 47 deletions(-) diff --git a/NEWS b/NEWS index ada03481..cff8aab9 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ xbps-0.38 (???): + * libfetch: synchronized with NetBSD pkgsrc/libfetch. + * libfetch: add support for TLS SNI (Server Name Identification) from NetBSD, with some minor debug changes. This fixes GH issue #41 (https://github.com/voidlinux/xbps/issues/41). diff --git a/lib/Makefile b/lib/Makefile index c7a91d8a..8fb1be89 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -21,7 +21,7 @@ LIBPROP_CFLAGS += -fvisibility=hidden # libfetch LIBFETCH_OBJS = fetch/common.o fetch/fetch.o fetch/file.o LIBFETCH_OBJS += fetch/ftp.o fetch/http.o -LIBFETCH_CPPFLAGS = -D_GNU_SOURCE -DFTP_COMBINE_CWDS -DNETBSD -DINET6 -DWITH_SSL +LIBFETCH_CPPFLAGS = -DFTP_COMBINE_CWDS -DNETBSD -DINET6 -DWITH_SSL LIBFETCH_CFLAGS = -Wno-error -Wno-unused-macros -Wno-conversion ifdef HAVE_VISIBILITY LIBFETCH_CFLAGS+= -fvisibility=hidden diff --git a/lib/fetch/common.c b/lib/fetch/common.c index e34cacc5..60b13671 100644 --- a/lib/fetch/common.c +++ b/lib/fetch/common.c @@ -1,4 +1,4 @@ -/* $NetBSD: common.c,v 1.26 2010/03/21 16:48:43 joerg Exp $ */ +/* $NetBSD: common.c,v 1.29 2014/01/08 20:25:34 joerg Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav * Copyright (c) 2008, 2010 Joerg Sonnenberger @@ -60,6 +60,7 @@ #include #include #include +#include #ifndef MSG_NOSIGNAL #include diff --git a/lib/fetch/common.h b/lib/fetch/common.h index 231fb022..63170907 100644 --- a/lib/fetch/common.h +++ b/lib/fetch/common.h @@ -1,4 +1,4 @@ -/* $NetBSD: common.h,v 1.16 2010/03/21 16:48:43 joerg Exp $ */ +/* $NetBSD: common.h,v 1.23 2014/01/08 20:25:34 joerg Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav * All rights reserved. @@ -45,9 +45,16 @@ #include #endif +#if defined(__GNUC__) && __GNUC__ >= 3 +#define LIBFETCH_PRINTFLIKE(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#else +#define LIBFETCH_PRINTFLIKE(fmtarg, firstvararg) +#endif + #if !defined(__sun) && !defined(__hpux) && !defined(__INTERIX) && \ !defined(__digital__) && !defined(__linux) && !defined(__MINT__) && \ - !defined(__sgi) + !defined(__sgi) && !defined(__minix) && !defined(__CYGWIN__) #define HAVE_SA_LEN #endif @@ -90,7 +97,7 @@ struct fetcherr { void fetch_seterr(struct fetcherr *, int); void fetch_syserr(void); -void fetch_info(const char *, ...); +void fetch_info(const char *, ...) LIBFETCH_PRINTFLIKE(1, 2); int fetch_default_port(const char *); int fetch_default_proxy_port(const char *); int fetch_bind(int, int, const char *); diff --git a/lib/fetch/fetch.c b/lib/fetch/fetch.c index 9b1ac278..7c733b1c 100644 --- a/lib/fetch/fetch.c +++ b/lib/fetch/fetch.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "fetch.h" #include "common.h" diff --git a/lib/fetch/ftp.c b/lib/fetch/ftp.c index c104d5f1..4baec173 100644 --- a/lib/fetch/ftp.c +++ b/lib/fetch/ftp.c @@ -1,4 +1,4 @@ -/* $NetBSD: ftp.c,v 1.35 2010/03/21 16:48:43 joerg Exp $ */ +/* $NetBSD: ftp.c,v 1.46 2014/06/11 13:12:12 joerg Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav * Copyright (c) 2008, 2009, 2010 Joerg Sonnenberger @@ -42,7 +42,7 @@ * * Major Changelog: * - * Dag-Erling Coïdan Smørgrav + * Dag-Erling CoýÅan Smgrav * 9 Jun 1998 * * Incorporated into libfetch @@ -57,10 +57,9 @@ * */ -#include "compat.h" - -#ifndef NETBSD -#include +#ifdef __linux__ +/* Keep this down to Linux, it can create surprises else where. */ +#define _GNU_SOURCE #endif #include @@ -96,6 +95,7 @@ #pragma clang diagnostic ignored "-Wformat-nonliteral" #endif +static int ftp_cmd(conn_t *, const char *, ...) LIBFETCH_PRINTFLIKE(2, 3); #define FTP_ANONYMOUS_USER "anonymous" #define FTP_CONNECTION_ALREADY_OPEN 125 @@ -143,7 +143,11 @@ unmappedaddr(struct sockaddr_in6 *sin6, socklen_t *len) !IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) return; sin4 = (struct sockaddr_in *)sin6; - addr = *(uint8_t *)&sin6->sin6_addr.s6_addr[12]; +#ifdef s6_addr32 + addr = sin6->sin6_addr.s6_addr32[3]; +#else + memcpy(&addr, &sin6->sin6_addr.s6_addr[12], sizeof(addr)); +#endif port = sin6->sin6_port; memset(sin4, 0, sizeof(struct sockaddr_in)); sin4->sin_addr.s_addr = addr; @@ -194,6 +198,7 @@ ftp_chkerr(conn_t *conn) /* * Send a command and check reply */ +LIBFETCH_PRINTFLIKE(2, 3) static int ftp_cmd(conn_t *conn, const char *fmt, ...) { @@ -323,7 +328,8 @@ ftp_cwd(conn_t *conn, const char *path, int subdir) } else if (strcmp(conn->ftp_home, "/") == 0) { dst = strdup(path - 1); } else { - e = asprintf(&dst, "%s/%s", conn->ftp_home, path); + if (asprintf(&dst, "%s/%s", conn->ftp_home, path) == -1) + dst = NULL; } if (dst == NULL) { fetch_syserr(); @@ -384,7 +390,7 @@ ftp_cwd(conn_t *conn, const char *path, int subdir) ++beg, ++i; for (++i; dst + i < end && dst[i] != '/'; ++i) /* nothing */ ; - e = ftp_cmd(conn, "CWD %.*s\r\n", dst + i - beg, beg); + e = ftp_cmd(conn, "CWD %.*s\r\n", (int)(dst + i - beg), beg); if (e != FTP_FILE_ACTION_OK) { free(dst); ftp_seterr(e); @@ -462,7 +468,7 @@ ftp_stat(conn_t *conn, const char *file, struct url_stat *us) { char *ln; const char *filename; - int filenamelen, type; + int filenamelen, type, year; struct tm tm; time_t t; int e; @@ -477,7 +483,7 @@ ftp_stat(conn_t *conn, const char *file, struct url_stat *us) return (-1); } - e = ftp_cmd(conn, "SIZE %.*s\r\n", filenamelen, filename); + e = ftp_cmd(conn, "SIZE %.*s\r\n", (int)filenamelen, filename); if (e != FTP_FILE_STATUS) { ftp_seterr(e); return (-1); @@ -494,7 +500,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\r\n", filenamelen, filename); + e = ftp_cmd(conn, "MDTM %.*s\r\n", (int)filenamelen, filename); if (e != FTP_FILE_STATUS) { ftp_seterr(e); return (-1); @@ -514,13 +520,13 @@ ftp_stat(conn_t *conn, const char *file, struct url_stat *us) return (-1); } if (sscanf(ln, "%04d%02d%02d%02d%02d%02d", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { ftp_seterr(FTP_PROTOCOL_ERROR); return (-1); } tm.tm_mon--; - tm.tm_year -= 1900; + tm.tm_year = year - 1900; tm.tm_isdst = -1; t = timegm(&tm); if (t == (time_t)-1) @@ -837,7 +843,7 @@ retry_mode: e = ftp_cmd(conn, "%s%s%s\r\n", oper, *op_arg ? " " : "", op_arg); else e = ftp_cmd(conn, "%s %.*s\r\n", oper, - filenamelen, filename); + (int)filenamelen, filename); if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) goto ouch; @@ -846,9 +852,9 @@ retry_mode: uint16_t p; #if defined(IPV6_PORTRANGE) || defined(IP_PORTRANGE) int arg; + int low = CHECK_FLAG('l'); #endif int d; - char *ap; char hname[INET6_ADDRSTRLEN]; switch (u.ss.ss_family) { @@ -891,7 +897,6 @@ retry_mode: (p >> 8) & 0xff, p & 0xff); break; case AF_INET6: -#define UC(b) (((int)b)&0xff) e = -1; u.sin6.sin6_scope_id = 0; if (getnameinfo(&u.sa, l, @@ -903,17 +908,21 @@ retry_mode: goto ouch; } if (e != FTP_OK) { - ap = (char *)&u.sin6.sin6_addr; + unsigned char *ap = (void *)&u.sin6.sin6_addr.s6_addr; + uint16_t port = ntohs(u.sin6.sin6_port); 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\r\n", + "LPRT %d,%d,%u,%u,%u,%u,%u,%u,%u,%u," + "%u,%u,%u,%u,%u,%u,%u,%u,%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]), - UC(ap[8]), UC(ap[9]), UC(ap[10]), UC(ap[11]), - UC(ap[12]), UC(ap[13]), UC(ap[14]), UC(ap[15]), - 2, - (ntohs(u.sin6.sin6_port) >> 8) & 0xff, - ntohs(u.sin6.sin6_port) & 0xff); + (unsigned)ap[0], (unsigned)ap[1], + (unsigned)ap[2], (unsigned)ap[3], + (unsigned)ap[4], (unsigned)ap[5], + (unsigned)ap[6], (unsigned)ap[7], + (unsigned)ap[8], (unsigned)ap[9], + (unsigned)ap[10], (unsigned)ap[11], + (unsigned)ap[12], (unsigned)ap[13], + (unsigned)ap[14], (unsigned)ap[15], + 2, port >> 8, port & 0xff); } break; default: @@ -935,7 +944,7 @@ retry_mode: e = ftp_cmd(conn, "%s%s%s\r\n", oper, *op_arg ? " " : "", op_arg); else e = ftp_cmd(conn, "%s %.*s\r\n", oper, - filenamelen, filename); + (int)filenamelen, filename); if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) goto ouch; @@ -1151,12 +1160,14 @@ ftp_request(struct url *url, const char *op, const char *op_arg, return (NULL); if ((path = fetchUnquotePath(url)) == NULL) { + fetch_close(conn); fetch_syserr(); return NULL; } /* change directory */ if (ftp_cwd(conn, path, op_arg != NULL) == -1) { + fetch_close(conn); free(path); return (NULL); } @@ -1169,12 +1180,14 @@ ftp_request(struct url *url, const char *op, const char *op_arg, if (us && ftp_stat(conn, path, us) == -1 && fetchLastErrCode != FETCH_PROTO && fetchLastErrCode != FETCH_UNAVAIL) { + fetch_close(conn); free(path); return (NULL); } if (if_modified_since && url->last_modified > 0 && url->last_modified >= us->mtime) { + fetch_cache_put(conn, ftp_disconnect); free(path); fetchLastErrCode = FETCH_UNCHANGED; snprintf(fetchLastErrString, MAXERRSTRING, "Unchanged"); @@ -1183,6 +1196,7 @@ ftp_request(struct url *url, const char *op, const char *op_arg, /* just a stat */ if (strcmp(op, "STAT") == 0) { + fetch_cache_put(conn, ftp_disconnect); free(path); return fetchIO_unopen(NULL, NULL, NULL, NULL); } diff --git a/lib/fetch/http.c b/lib/fetch/http.c index 122d9c15..3285612e 100644 --- a/lib/fetch/http.c +++ b/lib/fetch/http.c @@ -1,6 +1,6 @@ -/* $NetBSD: http.c,v 1.28 2010/01/23 14:53:08 joerg Exp $ */ +/* $NetBSD: http.c,v 1.37 2014/06/11 13:12:12 joerg Exp $ */ /*- - * Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav + * Copyright (c) 2000-2004 Dag-Erling CoýÅan Smgrav * Copyright (c) 2003 Thomas Klausner * Copyright (c) 2008, 2009 Joerg Sonnenberger * All rights reserved. @@ -63,10 +63,13 @@ * SUCH DAMAGE. */ -#include "compat.h" - -#ifndef NETBSD -#include +#if defined(__linux__) || defined(__MINT__) || defined(__FreeBSD_kernel__) +/* Keep this down to Linux or MiNT, it can create surprises elsewhere. */ +/* + __FreeBSD_kernel__ is defined for GNU/kFreeBSD. + See http://glibc-bsd.alioth.debian.org/porting/PORTING . +*/ +#define _GNU_SOURCE #endif #include @@ -101,10 +104,6 @@ #include "common.h" #include "httperr.h" -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wformat-nonliteral" -#endif - /* Maximum number of redirects to follow */ #define MAX_REDIRECT 5 @@ -128,6 +127,7 @@ #define HTTP_ERROR(xyz) ((xyz) > 400 && (xyz) < 599) +static int http_cmd(conn_t *, const char *, ...) LIBFETCH_PRINTFLIKE(2, 3); /***************************************************************************** * I/O functions for decoding chunked streams @@ -324,7 +324,7 @@ http_closefn(void *v) fetch_cache_put(io->conn, fetch_close); #ifdef TCP_NOPUSH val = 1; - setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, + setsockopt(io->conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val)); #endif } else { @@ -399,6 +399,7 @@ static struct { /* * Send a formatted line; optionally echo to terminal */ +LIBFETCH_PRINTFLIKE(2, 3) static int http_cmd(conn_t *conn, const char *fmt, ...) { @@ -740,9 +741,8 @@ http_connect(struct url *URL, struct url *purl, const char *flags, int *cached) if ((conn = fetch_connect(URL, af, verbose)) == NULL) /* fetch_connect() has already set an error code */ return (NULL); - if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && - fetch_ssl(conn, URL, verbose) != 0) { + fetch_ssl(conn, URL, verbose) == -1) { fetch_close(conn); /* grrr */ #ifdef EAUTH @@ -793,9 +793,9 @@ set_if_modified_since(conn_t *conn, time_t last_modified) struct tm tm; char buf[80]; gmtime_r(&last_modified, &tm); - snprintf(buf, sizeof(buf), "%.3s, %02d %.3s %4d %02d:%02d:%02d GMT", + snprintf(buf, sizeof(buf), "%.3s, %02d %.3s %4ld %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); + (long)(tm.tm_year + 1900), tm.tm_hour, tm.tm_min, tm.tm_sec); http_cmd(conn, "If-Modified-Since: %s\r\n", buf); }