version 1.200, 2021/02/02 12:58:42 |
version 1.201, 2021/02/16 16:27:34 |
|
|
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
#include <util.h> |
|
#include <resolv.h> |
#include <resolv.h> |
#include <utime.h> |
#include <utime.h> |
|
|
|
|
static char hextochar(const char *); |
static char hextochar(const char *); |
static char *urldecode(const char *); |
static char *urldecode(const char *); |
static char *recode_credentials(const char *_userinfo); |
static char *recode_credentials(const char *_userinfo); |
static char *ftp_readline(FILE *, size_t *); |
|
static void ftp_close(FILE **, struct tls **, int *); |
static void ftp_close(FILE **, struct tls **, int *); |
static const char *sockerror(struct tls *); |
static const char *sockerror(struct tls *); |
#ifdef SMALL |
#ifdef SMALL |
|
|
off_t hashbytes; |
off_t hashbytes; |
const char *errstr; |
const char *errstr; |
ssize_t len, wlen; |
ssize_t len, wlen; |
|
size_t bufsize; |
char *proxyhost = NULL; |
char *proxyhost = NULL; |
#ifndef NOSSL |
#ifndef NOSSL |
char *sslpath = NULL, *sslhost = NULL; |
char *sslpath = NULL, *sslhost = NULL; |
|
|
free(buf); |
free(buf); |
#endif /* !NOSSL */ |
#endif /* !NOSSL */ |
buf = NULL; |
buf = NULL; |
|
bufsize = 0; |
|
|
if (fflush(fin) == EOF) { |
if (fflush(fin) == EOF) { |
warnx("Writing HTTP request: %s", sockerror(tls)); |
warnx("Writing HTTP request: %s", sockerror(tls)); |
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
if ((buf = ftp_readline(fin, &len)) == NULL) { |
if ((len = getline(&buf, &bufsize, fin)) == -1) { |
warnx("Receiving HTTP reply: %s", sockerror(tls)); |
warnx("Receiving HTTP reply: %s", sockerror(tls)); |
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
|
|
/* |
/* |
* Read the rest of the header. |
* Read the rest of the header. |
*/ |
*/ |
free(buf); |
|
filesize = -1; |
filesize = -1; |
|
|
for (;;) { |
for (;;) { |
if ((buf = ftp_readline(fin, &len)) == NULL) { |
if ((len = getline(&buf, &bufsize, fin)) == -1) { |
warnx("Receiving HTTP reply: %s", sockerror(tls)); |
warnx("Receiving HTTP reply: %s", sockerror(tls)); |
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
|
|
server_timestamps = 0; |
server_timestamps = 0; |
#endif /* !SMALL */ |
#endif /* !SMALL */ |
} |
} |
free(buf); |
|
} |
} |
|
free(buf); |
|
|
/* Content-Length should be ignored for Transfer-Encoding: chunked */ |
/* Content-Length should be ignored for Transfer-Encoding: chunked */ |
if (chunked) |
if (chunked) |
|
|
#endif |
#endif |
} |
} |
|
|
free(buf); |
|
if ((buf = malloc(buflen)) == NULL) |
if ((buf = malloc(buflen)) == NULL) |
errx(1, "Can't allocate memory for transfer buffer"); |
errx(1, "Can't allocate memory for transfer buffer"); |
|
|
|
|
save_chunked(FILE *fin, struct tls *tls, int out, char *buf, size_t buflen) |
save_chunked(FILE *fin, struct tls *tls, int out, char *buf, size_t buflen) |
{ |
{ |
|
|
char *header, *end, *cp; |
char *header = NULL, *end, *cp; |
unsigned long chunksize; |
unsigned long chunksize; |
size_t hlen, rlen, wlen; |
size_t hsize = 0, rlen, wlen; |
ssize_t written; |
ssize_t written; |
char cr, lf; |
char cr, lf; |
|
|
for (;;) { |
for (;;) { |
header = ftp_readline(fin, &hlen); |
if (getline(&header, &hsize, fin) == -1) |
if (header == NULL) |
|
break; |
break; |
/* strip CRLF and any optional chunk extension */ |
/* strip CRLF and any optional chunk extension */ |
header[strcspn(header, ";\r\n")] = '\0'; |
header[strcspn(header, ";\r\n")] = '\0'; |
|
|
free(header); |
free(header); |
return -1; |
return -1; |
} |
} |
free(header); |
|
|
|
if (chunksize == 0) { |
if (chunksize == 0) { |
/* We're done. Ignore optional trailer. */ |
/* We're done. Ignore optional trailer. */ |
|
free(header); |
return 0; |
return 0; |
} |
} |
|
|
|
|
wlen -= written, cp += written) { |
wlen -= written, cp += written) { |
if ((written = write(out, cp, wlen)) == -1) { |
if ((written = write(out, cp, wlen)) == -1) { |
warn("Writing output file"); |
warn("Writing output file"); |
|
free(header); |
return -1; |
return -1; |
} |
} |
} |
} |
|
|
|
|
if (cr != '\r' || lf != '\n') { |
if (cr != '\r' || lf != '\n') { |
warnx("Invalid chunked encoding"); |
warnx("Invalid chunked encoding"); |
|
free(header); |
return -1; |
return -1; |
} |
} |
} |
} |
|
free(header); |
|
|
if (ferror(fin)) |
if (ferror(fin)) |
warnx("Error while reading from socket: %s", sockerror(tls)); |
warnx("Error while reading from socket: %s", sockerror(tls)); |
|
|
strstr(p, ":/")) |
strstr(p, ":/")) |
return (1); |
return (1); |
return (0); |
return (0); |
} |
|
|
|
static char * |
|
ftp_readline(FILE *fp, size_t *lenp) |
|
{ |
|
return fparseln(fp, lenp, NULL, "\0\0\0", 0); |
|
} |
} |
|
|
#ifndef SMALL |
#ifndef SMALL |