Add modern FTP search providers for 1.2.4
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(libprozilla VERSION 1.2.3 LANGUAGES C)
|
||||
project(libprozilla VERSION 1.2.4 LANGUAGES C)
|
||||
|
||||
include(CTest)
|
||||
|
||||
|
||||
@@ -65,4 +65,4 @@ prozilla-dev:
|
||||
Homepage
|
||||
--------
|
||||
|
||||
prozilla.genesys.ro
|
||||
https://prozilla.disconnected-by-peer.at
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: libprozilla 1.2.3\n"
|
||||
"Project-Id-Version: libprozilla 1.2.4\n"
|
||||
"Report-Msgid-Bugs-To: prozilla-dev@disconnected-by-peer.at\n"
|
||||
"POT-Creation-Date: 2026-07-14 19:48+0200\n"
|
||||
"PO-Revision-Date: 2026-07-14 19:48+0200\n"
|
||||
|
||||
@@ -10,6 +10,7 @@ target_include_directories(prozilla
|
||||
PRIVATE "${PROJECT_BINARY_DIR}/generated")
|
||||
target_compile_definitions(prozilla PRIVATE HAVE_CONFIG_H=1 _GNU_SOURCE LOCALEDIR="${LOCALEDIR}")
|
||||
target_compile_options(prozilla PRIVATE $<$<COMPILE_LANG_AND_ID:C,GNU,Clang>:-Wall;-Wextra>)
|
||||
target_compile_options(prozilla PRIVATE $<$<COMPILE_LANG_AND_ID:C,GNU>:-Wno-clobbered>)
|
||||
target_link_libraries(prozilla PUBLIC Threads::Threads)
|
||||
target_link_libraries(prozilla PRIVATE CURL::libcurl)
|
||||
if(Intl_FOUND)
|
||||
|
||||
+1
-3
@@ -199,9 +199,7 @@ int select_fd(int fd, struct timeval *timeout, int writep)
|
||||
int krecv(int sock, char *buffer, int size, int flags,
|
||||
struct timeval *timeout)
|
||||
{
|
||||
int ret, arglen;
|
||||
|
||||
arglen = sizeof(int);
|
||||
int ret;
|
||||
|
||||
assert(size >= 0);
|
||||
|
||||
|
||||
+8
-6
@@ -160,7 +160,7 @@ uerr_t connection_retr_fsize_not_known(connection_t * connection,
|
||||
char *read_buffer,
|
||||
int read_buffer_size)
|
||||
{
|
||||
off_t bytes_read;
|
||||
int bytes_read;
|
||||
|
||||
connection_change_status(connection, DOWNLOADING);
|
||||
gettimeofday(&connection->time_begin, NULL);
|
||||
@@ -172,7 +172,8 @@ uerr_t connection_retr_fsize_not_known(connection_t * connection,
|
||||
&connection->xfer_timeout);
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
if (write_data_with_lock(connection, read_buffer, sizeof(char), bytes_read) < bytes_read)
|
||||
if (write_data_with_lock(connection, read_buffer, sizeof(char),
|
||||
(size_t)bytes_read) < (size_t)bytes_read)
|
||||
{
|
||||
proz_debug(_("write failed"));
|
||||
connection_show_message(connection,
|
||||
@@ -224,7 +225,7 @@ uerr_t connection_retr_fsize_not_known(connection_t * connection,
|
||||
uerr_t connection_retr_fsize_known(connection_t * connection,
|
||||
char *read_buffer, int read_buffer_size)
|
||||
{
|
||||
off_t bytes_read;
|
||||
int bytes_read;
|
||||
off_t bytes_to_get;
|
||||
|
||||
pthread_mutex_lock(&connection->access_mutex);
|
||||
@@ -266,7 +267,8 @@ uerr_t connection_retr_fsize_known(connection_t * connection,
|
||||
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
if (write_data_with_lock(connection, read_buffer, sizeof(char), bytes_read) < bytes_read)
|
||||
if (write_data_with_lock(connection, read_buffer, sizeof(char),
|
||||
(size_t)bytes_read) < (size_t)bytes_read)
|
||||
{
|
||||
proz_debug(_("write failed"));
|
||||
connection_show_message(connection,
|
||||
@@ -329,7 +331,7 @@ dl_status proz_connection_get_status(connection_t * connection)
|
||||
|
||||
|
||||
/*This will return a textual representation of the status of a conenction. */
|
||||
char *proz_connection_get_status_string(connection_t * connection)
|
||||
const char *proz_connection_get_status_string(connection_t * connection)
|
||||
{
|
||||
dl_status status;
|
||||
|
||||
@@ -337,7 +339,7 @@ char *proz_connection_get_status_string(connection_t * connection)
|
||||
status = connection->status;
|
||||
pthread_mutex_unlock(connection->status_change_mutex);
|
||||
|
||||
switch (connection->status)
|
||||
switch (status)
|
||||
{
|
||||
case IDLE:
|
||||
return(_("Idle"));
|
||||
|
||||
@@ -625,7 +625,6 @@ uerr_t ftp_login(connection_t * connection, const char *username,
|
||||
{
|
||||
uerr_t err = FTPERR;
|
||||
int ret_code = 220;
|
||||
boolean logged_in = FALSE;
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -688,7 +687,6 @@ uerr_t ftp_login(connection_t * connection, const char *username,
|
||||
case 231: /* Fallthrough. */
|
||||
case 202:
|
||||
|
||||
logged_in = TRUE;
|
||||
|
||||
if (!ftp_use_proxy(connection))
|
||||
return FTPOK; /* Logged in succesfully. */
|
||||
|
||||
+2
-3
@@ -188,6 +188,7 @@ uerr_t ftp_parse(ftpparse *fp, char *buf, int len)
|
||||
if (*buf == 'l')
|
||||
fp->filetype = SYMBOLIC_LINK;
|
||||
ptr = cp = strdup(buf);
|
||||
(void)ptr;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
@@ -235,9 +236,7 @@ uerr_t ftp_parse(ftpparse *fp, char *buf, int len)
|
||||
|
||||
time_t parse_time(const char * str)
|
||||
{
|
||||
char * p;
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
const char *p;
|
||||
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
+283
-5
@@ -26,13 +26,18 @@
|
||||
#include "ftpsearch.h"
|
||||
|
||||
|
||||
urlinfo *prepare_lycos_url(ftps_request_t * request, char *ftps_loc,
|
||||
urlinfo *prepare_lycos_url(ftps_request_t * request, const char *ftps_loc,
|
||||
int num_req_mirrors);
|
||||
urlinfo *prepare_filesearching_url(ftps_request_t * request, char *ftps_loc,
|
||||
urlinfo *prepare_filesearching_url(ftps_request_t * request, const char *ftps_loc,
|
||||
int num_req_mirrors);
|
||||
urlinfo *prepare_archie_url(ftps_request_t * request, const char *ftps_loc,
|
||||
int num_req_mirrors);
|
||||
urlinfo *prepare_mamont_url(ftps_request_t * request, const char *ftps_loc);
|
||||
|
||||
uerr_t parse_lycos_html_mirror_list(ftps_request_t * request, char *p);
|
||||
uerr_t parse_filesearching_html_mirror_list(ftps_request_t * request, char *p);
|
||||
uerr_t parse_archie_json_mirror_list(ftps_request_t * request, char *p);
|
||||
uerr_t parse_mamont_html_mirror_list(ftps_request_t * request, char *p);
|
||||
|
||||
uerr_t get_mirror_info(connection_t * connection, char **ret_buf);
|
||||
|
||||
@@ -52,7 +57,7 @@ ftp_mirror_t *reprocess_mirror_list(ftp_mirror_t * mirrors,
|
||||
|
||||
ftps_request_t * proz_ftps_request_init(
|
||||
urlinfo * requested_url, off_t file_size,
|
||||
char *ftps_loc,
|
||||
const char *ftps_loc,
|
||||
ftpsearch_server_type_t server_type,
|
||||
int num_req_mirrors)
|
||||
{
|
||||
@@ -92,6 +97,20 @@ ftps_request_t * proz_ftps_request_init(
|
||||
request->connection = proz_connection_init(url, 0);
|
||||
break;
|
||||
|
||||
case ARCHIE_JSON:
|
||||
url = prepare_archie_url(request, ftps_loc, num_req_mirrors);
|
||||
if (url == 0)
|
||||
proz_die("Bad URL specification");
|
||||
request->connection = proz_connection_init(url, 0);
|
||||
break;
|
||||
|
||||
case MAMONT_HTML:
|
||||
url = prepare_mamont_url(request, ftps_loc);
|
||||
if (url == 0)
|
||||
proz_die("Bad URL specification");
|
||||
request->connection = proz_connection_init(url, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
proz_debug("Unsupported FTP search server type");
|
||||
proz_die("Unsupported FTP search server type");
|
||||
@@ -101,7 +120,78 @@ ftps_request_t * proz_ftps_request_init(
|
||||
}
|
||||
|
||||
|
||||
urlinfo *prepare_lycos_url(ftps_request_t * request, char *ftps_loc,
|
||||
static char *url_encode_component(const char *input)
|
||||
{
|
||||
static const char hex[] = "0123456789ABCDEF";
|
||||
size_t input_len = strlen(input);
|
||||
char *encoded = kmalloc(input_len * 3 + 1);
|
||||
char *out = encoded;
|
||||
|
||||
while (*input)
|
||||
{
|
||||
unsigned char ch = (unsigned char)*input++;
|
||||
if (isalnum(ch) || ch == '-' || ch == '_' || ch == '.' || ch == '~')
|
||||
*out++ = (char)ch;
|
||||
else
|
||||
{
|
||||
*out++ = '%';
|
||||
*out++ = hex[ch >> 4];
|
||||
*out++ = hex[ch & 15];
|
||||
}
|
||||
}
|
||||
*out = '\0';
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
urlinfo *prepare_archie_url(ftps_request_t * request, const char *ftps_loc,
|
||||
int num_req_mirrors)
|
||||
{
|
||||
urlinfo *url = kmalloc(sizeof(*url));
|
||||
char *encoded_name = url_encode_component(request->file_name);
|
||||
size_t length = strlen(ftps_loc) + strlen(encoded_name) + 80;
|
||||
char *request_url = kmalloc(length);
|
||||
uerr_t err;
|
||||
|
||||
snprintf(request_url, length,
|
||||
"%s?q=%s&type=exact&database=anonftp&limit=%d",
|
||||
ftps_loc, encoded_name, num_req_mirrors);
|
||||
proz_debug("ftpsearch url= %s\n", request_url);
|
||||
err = proz_parse_url(request_url, url, 0);
|
||||
kfree(encoded_name);
|
||||
kfree(request_url);
|
||||
if (err != URLOK)
|
||||
{
|
||||
kfree(url);
|
||||
return 0;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
urlinfo *prepare_mamont_url(ftps_request_t * request, const char *ftps_loc)
|
||||
{
|
||||
urlinfo *url = kmalloc(sizeof(*url));
|
||||
char *encoded_name = url_encode_component(request->file_name);
|
||||
size_t length = strlen(ftps_loc) + strlen(encoded_name) + 16;
|
||||
char *request_url = kmalloc(length);
|
||||
uerr_t err;
|
||||
|
||||
snprintf(request_url, length, "%s?st=%s", ftps_loc, encoded_name);
|
||||
proz_debug("ftpsearch url= %s\n", request_url);
|
||||
err = proz_parse_url(request_url, url, 0);
|
||||
kfree(encoded_name);
|
||||
kfree(request_url);
|
||||
if (err != URLOK)
|
||||
{
|
||||
kfree(url);
|
||||
return 0;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
urlinfo *prepare_lycos_url(ftps_request_t * request, const char *ftps_loc,
|
||||
int num_req_mirrors)
|
||||
{
|
||||
urlinfo *url;
|
||||
@@ -141,7 +231,7 @@ urlinfo *prepare_lycos_url(ftps_request_t * request, char *ftps_loc,
|
||||
|
||||
|
||||
|
||||
urlinfo *prepare_filesearching_url(ftps_request_t * request, char *ftps_loc,
|
||||
urlinfo *prepare_filesearching_url(ftps_request_t * request, const char *ftps_loc,
|
||||
int num_req_mirrors)
|
||||
{
|
||||
urlinfo *url;
|
||||
@@ -193,6 +283,12 @@ uerr_t parse_html_mirror_list(ftps_request_t * request, char *p)
|
||||
return parse_filesearching_html_mirror_list(request, p);
|
||||
break;
|
||||
|
||||
case ARCHIE_JSON:
|
||||
return parse_archie_json_mirror_list(request, p);
|
||||
|
||||
case MAMONT_HTML:
|
||||
return parse_mamont_html_mirror_list(request, p);
|
||||
|
||||
default:
|
||||
proz_debug("Unsupported FTP search server type");
|
||||
proz_die("Unsupported FTP search server type");
|
||||
@@ -200,6 +296,188 @@ uerr_t parse_html_mirror_list(ftps_request_t * request, char *p)
|
||||
return MIRPARSEFAIL;
|
||||
}
|
||||
|
||||
|
||||
static const char *json_url_value(const char *cursor, char *output,
|
||||
size_t output_size)
|
||||
{
|
||||
const char *key = strstr(cursor, "\"URL\"");
|
||||
size_t used = 0;
|
||||
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
cursor = key + 5;
|
||||
while (isspace((unsigned char)*cursor))
|
||||
cursor++;
|
||||
if (*cursor++ != ':')
|
||||
return json_url_value(cursor, output, output_size);
|
||||
while (isspace((unsigned char)*cursor))
|
||||
cursor++;
|
||||
if (*cursor++ != '\"')
|
||||
return json_url_value(cursor, output, output_size);
|
||||
|
||||
while (*cursor && *cursor != '\"')
|
||||
{
|
||||
unsigned char ch = (unsigned char)*cursor++;
|
||||
if (ch == '\\')
|
||||
{
|
||||
ch = (unsigned char)*cursor++;
|
||||
if (ch == 'n') ch = '\n';
|
||||
else if (ch == 'r') ch = '\r';
|
||||
else if (ch == 't') ch = '\t';
|
||||
else if (ch == 'b') ch = '\b';
|
||||
else if (ch == 'f') ch = '\f';
|
||||
else if (ch == 'u')
|
||||
{
|
||||
/* FTP URLs are ASCII; skip a JSON Unicode escape safely. */
|
||||
for (int i = 0; i < 4 && isxdigit((unsigned char)*cursor); i++)
|
||||
cursor++;
|
||||
ch = '?';
|
||||
}
|
||||
}
|
||||
if (used + 1 < output_size)
|
||||
output[used++] = (char)ch;
|
||||
}
|
||||
output[used] = '\0';
|
||||
return *cursor == '\"' ? cursor + 1 : cursor;
|
||||
}
|
||||
|
||||
|
||||
uerr_t parse_archie_json_mirror_list(ftps_request_t * request, char *p)
|
||||
{
|
||||
ftp_mirror_t *mirrors;
|
||||
const char *cursor = p;
|
||||
int capacity = 1;
|
||||
int count = 0;
|
||||
char url_string[4096];
|
||||
|
||||
while ((cursor = strstr(cursor, "\"URL\"")) != NULL)
|
||||
{
|
||||
capacity++;
|
||||
cursor += 5;
|
||||
}
|
||||
mirrors = kmalloc(sizeof(*mirrors) * (size_t)capacity);
|
||||
cursor = p;
|
||||
|
||||
while ((cursor = json_url_value(cursor, url_string,
|
||||
sizeof(url_string))) != NULL)
|
||||
{
|
||||
urlinfo parsed;
|
||||
if (proz_parse_url(url_string, &parsed, 0) != URLOK)
|
||||
continue;
|
||||
if (parsed.proto != URLFTP && parsed.proto != URLFTPS &&
|
||||
parsed.proto != URLSFTP)
|
||||
{
|
||||
proz_free_url(&parsed, FALSE);
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&mirrors[count], 0, sizeof(mirrors[count]));
|
||||
mirrors[count].server_name = kstrdup(parsed.host);
|
||||
mirrors[count].paths = kmalloc(sizeof(mirror_path_t));
|
||||
mirrors[count].num_paths = 1;
|
||||
mirrors[count].paths[0].path = kstrdup(parsed.dir ? parsed.dir : "");
|
||||
mirrors[count].paths[0].valid = TRUE;
|
||||
mirrors[count].file_name = kstrdup(parsed.file);
|
||||
mirrors[count].full_name = kstrdup(url_string);
|
||||
count++;
|
||||
proz_free_url(&parsed, FALSE);
|
||||
}
|
||||
|
||||
if (request->requested_url->proto == URLFTP ||
|
||||
request->requested_url->proto == URLFTPS ||
|
||||
request->requested_url->proto == URLSFTP)
|
||||
{
|
||||
urlinfo *original = request->requested_url;
|
||||
memset(&mirrors[count], 0, sizeof(mirrors[count]));
|
||||
mirrors[count].server_name = kstrdup(original->host);
|
||||
mirrors[count].paths = kmalloc(sizeof(mirror_path_t));
|
||||
mirrors[count].num_paths = 1;
|
||||
mirrors[count].paths[0].path = kstrdup(original->dir ? original->dir : "");
|
||||
mirrors[count].paths[0].valid = TRUE;
|
||||
mirrors[count].file_name = kstrdup(original->file);
|
||||
mirrors[count].full_name = str_url(original, 1);
|
||||
count++;
|
||||
}
|
||||
|
||||
request->num_mirrors = count;
|
||||
request->mirrors = reprocess_mirror_list(mirrors, &request->num_mirrors);
|
||||
return MIRINFOK;
|
||||
}
|
||||
|
||||
|
||||
uerr_t parse_mamont_html_mirror_list(ftps_request_t * request, char *p)
|
||||
{
|
||||
static const char marker[] = "href=\"ftp://";
|
||||
ftp_mirror_t *mirrors;
|
||||
const char *cursor = p;
|
||||
int capacity = 1;
|
||||
int count = 0;
|
||||
|
||||
while ((cursor = strstr(cursor, marker)) != NULL)
|
||||
{
|
||||
capacity++;
|
||||
cursor += sizeof(marker) - 1;
|
||||
}
|
||||
mirrors = kmalloc(sizeof(*mirrors) * (size_t)capacity);
|
||||
cursor = p;
|
||||
|
||||
while ((cursor = strstr(cursor, marker)) != NULL)
|
||||
{
|
||||
urlinfo parsed;
|
||||
const char *start = cursor + 6;
|
||||
const char *end = strchr(start, '\"');
|
||||
size_t length;
|
||||
char *url_string;
|
||||
|
||||
if (end == NULL)
|
||||
break;
|
||||
cursor = end + 1;
|
||||
length = (size_t)(end - start);
|
||||
if (length == 0 || length >= 4096)
|
||||
continue;
|
||||
url_string = kmalloc(length + 1);
|
||||
memcpy(url_string, start, length);
|
||||
url_string[length] = '\0';
|
||||
|
||||
if (proz_parse_url(url_string, &parsed, 0) != URLOK ||
|
||||
parsed.proto != URLFTP)
|
||||
{
|
||||
kfree(url_string);
|
||||
continue;
|
||||
}
|
||||
memset(&mirrors[count], 0, sizeof(mirrors[count]));
|
||||
mirrors[count].server_name = kstrdup(parsed.host);
|
||||
mirrors[count].paths = kmalloc(sizeof(mirror_path_t));
|
||||
mirrors[count].num_paths = 1;
|
||||
mirrors[count].paths[0].path = kstrdup(parsed.dir ? parsed.dir : "");
|
||||
mirrors[count].paths[0].valid = TRUE;
|
||||
mirrors[count].file_name = kstrdup(parsed.file);
|
||||
mirrors[count].full_name = url_string;
|
||||
count++;
|
||||
proz_free_url(&parsed, FALSE);
|
||||
}
|
||||
|
||||
if (request->requested_url->proto == URLFTP ||
|
||||
request->requested_url->proto == URLFTPS ||
|
||||
request->requested_url->proto == URLSFTP)
|
||||
{
|
||||
urlinfo *original = request->requested_url;
|
||||
memset(&mirrors[count], 0, sizeof(mirrors[count]));
|
||||
mirrors[count].server_name = kstrdup(original->host);
|
||||
mirrors[count].paths = kmalloc(sizeof(mirror_path_t));
|
||||
mirrors[count].num_paths = 1;
|
||||
mirrors[count].paths[0].path = kstrdup(original->dir ? original->dir : "");
|
||||
mirrors[count].paths[0].valid = TRUE;
|
||||
mirrors[count].file_name = kstrdup(original->file);
|
||||
mirrors[count].full_name = str_url(original, 1);
|
||||
count++;
|
||||
}
|
||||
|
||||
request->num_mirrors = count;
|
||||
request->mirrors = reprocess_mirror_list(mirrors, &request->num_mirrors);
|
||||
return MIRINFOK;
|
||||
}
|
||||
|
||||
uerr_t parse_lycos_html_mirror_list(ftps_request_t * request, char *p)
|
||||
{
|
||||
struct ftp_mirror **pmirrors = &request->mirrors;
|
||||
|
||||
+2
-3
@@ -360,7 +360,7 @@ uerr_t http_fetch_headers(connection_t * connection, http_stat_t * hs,
|
||||
char *command)
|
||||
{
|
||||
uerr_t err;
|
||||
int num_written, hcount, statcode, all_length;
|
||||
int num_written, hcount, statcode;
|
||||
off_t contlen, contrange;
|
||||
char *hdr, *type, *all_headers;
|
||||
const char *error;
|
||||
@@ -375,14 +375,13 @@ uerr_t http_fetch_headers(connection_t * connection, http_stat_t * hs,
|
||||
|
||||
num_written = ksend(connection->data_sock, command, strlen(command), 0,
|
||||
&connection->xfer_timeout);
|
||||
if (num_written != strlen(command))
|
||||
if (num_written < 0 || (size_t)num_written != strlen(command))
|
||||
{
|
||||
proz_debug(_("Failed writing HTTP request"));
|
||||
return WRITEERR;
|
||||
}
|
||||
|
||||
all_headers = NULL;
|
||||
all_length = 0;
|
||||
contlen = contrange = -1;
|
||||
statcode = -1;
|
||||
type = NULL;
|
||||
|
||||
+1
-1
@@ -227,7 +227,7 @@ int proz_log_read_logfile(logfile * lf, download_t * download,
|
||||
|
||||
lf->url = kmalloc(lf->url_len + 1);
|
||||
|
||||
if (fread(lf->url, 1, lf->url_len, fp) != lf->url_len)
|
||||
if (fread(lf->url, 1, (size_t)lf->url_len, fp) != (size_t)lf->url_len)
|
||||
{
|
||||
fclose(fp);
|
||||
return -1;
|
||||
|
||||
+2
-2
@@ -54,8 +54,8 @@ int proz_init(int argc, char **argv)
|
||||
|
||||
/* Gettext stuff */
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
(void)bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
(void)textdomain(PACKAGE);
|
||||
|
||||
memset(&libprozrtinfo, 0, sizeof(libprozrtinfo));
|
||||
libprozrtinfo.argc = argc;
|
||||
|
||||
+1
-2
@@ -316,7 +316,7 @@ int close_sock(int *sock)
|
||||
|
||||
/*Returns a string representation of a prozilla errror */
|
||||
|
||||
char *proz_strerror(uerr_t error)
|
||||
const char *proz_strerror(uerr_t error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
@@ -568,4 +568,3 @@ void cleanup_httpsocks(connection_t * connection)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -349,7 +349,7 @@ typedef enum {
|
||||
} ftp_mirror_stat_t;
|
||||
|
||||
typedef enum {
|
||||
LYCOS, FILESEARCH_RU
|
||||
LYCOS, FILESEARCH_RU, ARCHIE_JSON, MAMONT_HTML
|
||||
} ftpsearch_server_type_t;
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@ void proz_debug_delete_log();
|
||||
connection_t * proz_connection_init(urlinfo * url, pthread_mutex_t * mutex);
|
||||
void proz_connection_set_url(connection_t * connection, urlinfo *url);
|
||||
|
||||
char *proz_connection_get_status_string(connection_t * connection);
|
||||
const char *proz_connection_get_status_string(connection_t * connection);
|
||||
off_t proz_connection_get_total_bytes_got(connection_t * connection);
|
||||
void proz_get_url_info_loop(connection_t * connection, pthread_t *thread);
|
||||
off_t proz_connection_get_total_remote_bytes_got(connection_t *
|
||||
@@ -538,12 +538,12 @@ int proz_log_read_logfile(logfile * lf, download_t * download,
|
||||
boolean load_con_info);
|
||||
int proz_log_delete_logfile(download_t * download);
|
||||
int proz_log_logfile_exists(download_t * download);
|
||||
char *proz_strerror(uerr_t error);
|
||||
const char *proz_strerror(uerr_t error);
|
||||
|
||||
/*Ftpsearch releated */
|
||||
ftps_request_t * proz_ftps_request_init(
|
||||
urlinfo * requested_url, off_t file_size,
|
||||
char *ftps_loc,
|
||||
const char *ftps_loc,
|
||||
ftpsearch_server_type_t server_type,
|
||||
int num_req_mirrors);
|
||||
void proz_get_complete_mirror_list(ftps_request_t * request);
|
||||
|
||||
@@ -134,7 +134,7 @@ enum {
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(*(array)))
|
||||
|
||||
const static unsigned char urlchr_table[256] = {
|
||||
static const unsigned char urlchr_table[256] = {
|
||||
U, U, U, U, U, U, U, U, /* NUL SOH STX ETX EOT ENQ ACK BEL */
|
||||
U, U, U, U, U, U, U, U, /* BS HT LF VT FF CR SO SI */
|
||||
U, U, U, U, U, U, U, U, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
|
||||
@@ -303,7 +303,7 @@ char *encode_string(const char *s)
|
||||
URLUNKNOWN if not. */
|
||||
uerr_t urlproto(const char *url)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sup_protos); i++)
|
||||
if (!strncasecmp(url, sup_protos[i].name, strlen(sup_protos[i].name)))
|
||||
@@ -613,7 +613,8 @@ static uerr_t parse_uname(const char *url, char **user, char **passwd)
|
||||
char *str_url(const urlinfo * u, int hide)
|
||||
{
|
||||
char *res, *host, *user, *passwd, *proto_name, *dir, *file;
|
||||
int i, l, ln, lu, lh, lp, lf, ld;
|
||||
size_t i;
|
||||
int l, ln, lu, lh, lp, lf, ld;
|
||||
unsigned short proto_default_port;
|
||||
|
||||
/* Look for the protocol name. */
|
||||
@@ -725,7 +726,8 @@ char *str_url(const urlinfo * u, int hide)
|
||||
form. */
|
||||
uerr_t proz_parse_url(const char *url, urlinfo * u, int strict)
|
||||
{
|
||||
int i, l, abs_ftp;
|
||||
size_t i;
|
||||
int l, abs_ftp;
|
||||
int recognizable; /* Recognizable URL is the one where
|
||||
the protocol name was explicitly
|
||||
named, i.e. it wasn't deduced from
|
||||
@@ -757,9 +759,9 @@ uerr_t proz_parse_url(const char *url, urlinfo * u, int strict)
|
||||
them for now). */
|
||||
if (recognizable)
|
||||
l += skip_uname(url + l);
|
||||
for (i = l; url[i] && url[i] != ':' && url[i] != '/'; i++)
|
||||
for (i = (size_t)l; url[i] && url[i] != ':' && url[i] != '/'; i++)
|
||||
;
|
||||
if (i == l)
|
||||
if (i == (size_t)l)
|
||||
return URLBADHOST;
|
||||
/* Get the hostname. */
|
||||
u->host = strdupdelim(url + l, url + i);
|
||||
@@ -791,7 +793,7 @@ uerr_t proz_parse_url(const char *url, urlinfo * u, int strict)
|
||||
u->proto = type = URLHTTP;
|
||||
if (!u->port)
|
||||
{
|
||||
int ind;
|
||||
size_t ind;
|
||||
for (ind = 0; ind < ARRAY_SIZE(sup_protos); ind++)
|
||||
if (sup_protos[ind].ind == type)
|
||||
break;
|
||||
@@ -937,12 +939,6 @@ urlpos *add_url(urlpos * l, const char *url, const char *file)
|
||||
}
|
||||
|
||||
|
||||
/*This will copy a url structure to another */
|
||||
void url_cpy(urlinfo * src, urlinfo * dest)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* Find the last occurrence of character C in the range [b, e), or
|
||||
NULL, if none are present. This is almost completely equivalent to
|
||||
{ *e = '\0'; return strrchr(b); }, except that it doesn't change
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
add_executable(url_parse_test url_parse_test.c)
|
||||
target_link_libraries(url_parse_test PRIVATE prozilla)
|
||||
add_test(NAME url_parse COMMAND url_parse_test)
|
||||
|
||||
add_executable(ftpsearch_parse_test ftpsearch_parse_test.c)
|
||||
target_link_libraries(ftpsearch_parse_test PRIVATE prozilla)
|
||||
add_test(NAME ftpsearch_parse COMMAND ftpsearch_parse_test)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "prozilla.h"
|
||||
|
||||
uerr_t parse_archie_json_mirror_list(ftps_request_t *request, char *data);
|
||||
uerr_t parse_mamont_html_mirror_list(ftps_request_t *request, char *data);
|
||||
|
||||
static void init_request(ftps_request_t *request, urlinfo *requested_url)
|
||||
{
|
||||
memset(request, 0, sizeof(*request));
|
||||
memset(requested_url, 0, sizeof(*requested_url));
|
||||
requested_url->proto = URLHTTP;
|
||||
request->requested_url = requested_url;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ftps_request_t request;
|
||||
urlinfo requested_url;
|
||||
char archie_json[] =
|
||||
"{\"hits\":2,\"results\":["
|
||||
"{\"URL\":\"ftp://ftp.example.org/pub/file.zip\"},"
|
||||
"{\"URL\":\"ftps://secure.example.org/releases/file.zip\"}]}";
|
||||
char mamont_html[] =
|
||||
"<a href=\"ftp://mirror.example.net/dist/file.zip\">file.zip</a>";
|
||||
|
||||
init_request(&request, &requested_url);
|
||||
assert(parse_archie_json_mirror_list(&request, archie_json) == MIRINFOK);
|
||||
assert(request.num_mirrors == 2);
|
||||
assert(strcmp(request.mirrors[0].server_name, "ftp.example.org") == 0);
|
||||
assert(strcmp(request.mirrors[1].server_name, "secure.example.org") == 0);
|
||||
|
||||
init_request(&request, &requested_url);
|
||||
assert(parse_mamont_html_mirror_list(&request, mamont_html) == MIRINFOK);
|
||||
assert(request.num_mirrors == 1);
|
||||
assert(strcmp(request.mirrors[0].server_name, "mirror.example.net") == 0);
|
||||
assert(strcmp(request.mirrors[0].file_name, "file.zip") == 0);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user