mirror of
https://github.com/xroche/httrack.git
synced 2026-05-19 09:26:16 +03:00
Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f8a15c76f | ||
|
|
40f237fe9c | ||
|
|
04cfb2db0e | ||
|
|
bdbf66b45c | ||
|
|
6bace27858 | ||
|
|
7d3d496a7f | ||
|
|
7826a49f59 | ||
|
|
ed79961b7a | ||
|
|
d3c14c9d1f | ||
|
|
7026ba7c7b | ||
|
|
abe98f238d | ||
|
|
8dd39bc909 | ||
|
|
17ec3ecd6b | ||
|
|
c7636d4f90 | ||
|
|
3a7e594166 | ||
|
|
b88395a16c | ||
|
|
4f5776a8fa | ||
|
|
8adeadbdb6 | ||
|
|
c64b8d6e88 | ||
|
|
194ebad4c6 | ||
|
|
ae6d05fbb3 | ||
|
|
803f7b5a33 | ||
|
|
f919aab408 | ||
|
|
0238301aca | ||
|
|
3864a45388 | ||
|
|
5e248cc4e3 | ||
|
|
473baf7f95 | ||
|
|
27752e368c | ||
|
|
37187f967f | ||
|
|
1d07610320 | ||
|
|
49304bbe8f | ||
|
|
11e069aa07 | ||
|
|
0c7a0274ca | ||
|
|
f3a4a20750 | ||
|
|
e090cd9ccf | ||
|
|
1bebff2697 | ||
|
|
c7fac4dbca | ||
|
|
0b52cac218 | ||
|
|
43b457203b | ||
|
|
fdcff762f6 | ||
|
|
c3987aca71 | ||
|
|
f67a86657b | ||
|
|
01edfd6d1e | ||
|
|
a300785d5e | ||
|
|
5364514f34 | ||
|
|
f078a39677 | ||
|
|
65454f4ff1 | ||
|
|
15813b5380 | ||
|
|
033ce293b8 | ||
|
|
d1913325e4 | ||
|
|
882578ed9a | ||
|
|
1ec8b5fb9e | ||
|
|
796c62f07c | ||
|
|
cefcc04266 | ||
|
|
6ba50a2001 | ||
|
|
9315f64b6e | ||
|
|
feb2a02cc2 | ||
|
|
24ff04fdb7 | ||
|
|
72e0c0601b | ||
|
|
b72741ddc9 | ||
|
|
1edfda507d | ||
|
|
4a62c84479 | ||
|
|
595d446470 | ||
|
|
0474c596b6 | ||
|
|
9f23ea7980 | ||
|
|
fe1ec5b0f6 | ||
|
|
fd1ab669ad | ||
|
|
34788bb7f6 | ||
|
|
03edb3eac8 | ||
|
|
fe7ea8b140 | ||
|
|
1fd27d74af | ||
|
|
08a17f31d4 | ||
|
|
6c8b76e531 | ||
|
|
66c8cc32aa | ||
|
|
2209c7bdd8 | ||
|
|
cb0460ddcb | ||
|
|
fb9e02ffb9 | ||
|
|
ac779cb6a0 | ||
|
|
0073d3ad05 | ||
|
|
638cc96917 | ||
|
|
c6e0ad4bce | ||
|
|
c457788a14 | ||
|
|
216005d33a | ||
|
|
59008af067 | ||
|
|
3059bd6f53 | ||
|
|
e5b3c85156 | ||
|
|
843faaf83d | ||
|
|
75969b1147 | ||
|
|
6ad604624d | ||
|
|
c05f54ae04 | ||
|
|
ae1db762e7 | ||
|
|
16aec722bf | ||
|
|
4ff55249ed | ||
|
|
fea8122ed3 | ||
|
|
7323230eb3 | ||
|
|
c9f656fdeb | ||
|
|
042525a1db | ||
|
|
3fde59c090 | ||
|
|
edaaa73328 |
@@ -108,3 +108,9 @@
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* in_port_t */
|
||||
#undef in_port_t
|
||||
|
||||
/* sa_family_t */
|
||||
#undef sa_family_t
|
||||
|
||||
50
configure
vendored
50
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for httrack 3.48.6.
|
||||
# Generated by GNU Autoconf 2.69 for httrack 3.48.9.
|
||||
#
|
||||
# Report bugs to <roche+packaging@httrack.com>.
|
||||
#
|
||||
@@ -590,8 +590,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='httrack'
|
||||
PACKAGE_TARNAME='httrack'
|
||||
PACKAGE_VERSION='3.48.6'
|
||||
PACKAGE_STRING='httrack 3.48.6'
|
||||
PACKAGE_VERSION='3.48.9'
|
||||
PACKAGE_STRING='httrack 3.48.9'
|
||||
PACKAGE_BUGREPORT='roche+packaging@httrack.com'
|
||||
PACKAGE_URL='http://www.httrack.com/'
|
||||
|
||||
@@ -1337,7 +1337,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures httrack 3.48.6 to adapt to many kinds of systems.
|
||||
\`configure' configures httrack 3.48.9 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1407,7 +1407,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of httrack 3.48.6:";;
|
||||
short | recursive ) echo "Configuration of httrack 3.48.9:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1521,7 +1521,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
httrack configure 3.48.6
|
||||
httrack configure 3.48.9
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2248,7 +2248,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by httrack $as_me 3.48.6, which was
|
||||
It was created by httrack $as_me 3.48.9, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -3067,7 +3067,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='httrack'
|
||||
VERSION='3.48.6'
|
||||
VERSION='3.48.9'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
@@ -15408,6 +15408,36 @@ $as_echo "$as_me: WARNING: *** in_addr_t not found" >&2;}
|
||||
fi
|
||||
|
||||
|
||||
# check for in_port_
|
||||
ac_fn_c_check_type "$LINENO" "in_port_t" "ac_cv_type_in_port_t" "
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_type_in_port_t" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
$as_echo "#define in_port_t uint16_t" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# check for sa_family_t
|
||||
ac_fn_c_check_type "$LINENO" "sa_family_t" "ac_cv_type_sa_family_t" "
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_type_sa_family_t" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
$as_echo "#define sa_family_t uint16_t" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
### zlib
|
||||
#
|
||||
# Handle user hints
|
||||
@@ -16892,7 +16922,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by httrack $as_me 3.48.6, which was
|
||||
This file was extended by httrack $as_me 3.48.9, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -16959,7 +16989,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
httrack config.status 3.48.6
|
||||
httrack config.status 3.48.9
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
14
configure.ac
14
configure.ac
@@ -1,4 +1,4 @@
|
||||
AC_INIT([httrack], [3.48.6], [roche+packaging@httrack.com], [httrack], [http://www.httrack.com/])
|
||||
AC_INIT([httrack], [3.48.9], [roche+packaging@httrack.com], [httrack], [http://www.httrack.com/])
|
||||
AC_CONFIG_SRCDIR(src/httrack.c)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
@@ -47,6 +47,18 @@ AC_MSG_WARN([*** in_addr_t not found]),
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>])
|
||||
|
||||
# check for in_port_
|
||||
AC_CHECK_TYPE(in_port_t, [], [AC_DEFINE([in_port_t], [uint16_t], [in_port_t])], [
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
])
|
||||
|
||||
# check for sa_family_t
|
||||
AC_CHECK_TYPE(sa_family_t, [], [AC_DEFINE([sa_family_t], [uint16_t], [sa_family_t])], [
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
])
|
||||
|
||||
### zlib
|
||||
CHECK_ZLIB()
|
||||
|
||||
|
||||
18
debian/changelog
vendored
18
debian/changelog
vendored
@@ -1,3 +1,21 @@
|
||||
httrack (3.48.9-1) unstable; urgency=low
|
||||
|
||||
* Updated to 3.48.9 (3.48-9)
|
||||
|
||||
-- Xavier Roche <xavier@debian.org> Wed, 21 May 2014 19:22:04 +0200
|
||||
|
||||
httrack (3.48.8-1) unstable; urgency=low
|
||||
|
||||
* Updated to 3.48.8 (3.48-8)
|
||||
|
||||
-- Xavier Roche <xavier@debian.org> Thu, 15 May 2014 19:21:21 +0200
|
||||
|
||||
httrack (3.48.7-1) unstable; urgency=low
|
||||
|
||||
* Updated to 3.48.7 (3.48-7)
|
||||
|
||||
-- Xavier Roche <xavier@debian.org> Wed, 14 May 2014 19:51:57 +0200
|
||||
|
||||
httrack (3.48.6-1) unstable; urgency=low
|
||||
|
||||
* Updated to 3.48.6 (3.48-6)
|
||||
|
||||
@@ -4,8 +4,12 @@ HTTrack Website Copier release history:
|
||||
|
||||
This file lists all changes and fixes that have been made for HTTrack.
|
||||
|
||||
3.48-6
|
||||
+ Fixed: mitigate the "hashtable internal error: cuckoo/stash collision" errors
|
||||
3.48-9
|
||||
+ Fixed: broken 32-bit version
|
||||
+ Fixed: assertion "segOutputSize < segSize assertion fails at htscharset.c:993"
|
||||
+ Fixed: new zlib version fixing CVE-2004-0797 and CVE-2005-2096
|
||||
+ Fixed: more reliable crash reporting
|
||||
+ Fixed: fixed infamous "hashtable internal error: cuckoo/stash collision" errors
|
||||
+ Fixed: safety cleanup in many strings operations
|
||||
+ Fixed: buggy option pannels
|
||||
+ New: Enforce check against CVE-2014-0160
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.\" Process this file with
|
||||
.\" groff -man -Tascii httrack.1
|
||||
.\"
|
||||
.TH httrack 1 "12 May 2014" "httrack website copier"
|
||||
.TH httrack 1 "15 May 2014" "httrack website copier"
|
||||
.SH NAME
|
||||
httrack \- offline browser : copy websites to a local directory
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -517,9 +517,9 @@ int optinclude_file(const char *name, int *argc, char **argv, char *x_argvblk,
|
||||
tmp_argv[1] = _tmp_argv[1];
|
||||
tmp_argv[2] = _tmp_argv[2];
|
||||
tmp_argv[3] = _tmp_argv[3];
|
||||
strcpybuff(tmp_argv[0], "--");
|
||||
strcatbuff(tmp_argv[0], a);
|
||||
strcpybuff(tmp_argv[1], b);
|
||||
strcpybuff(_tmp_argv[0], "--");
|
||||
strcatbuff(_tmp_argv[0], a);
|
||||
strcpybuff(_tmp_argv[1], b);
|
||||
|
||||
result =
|
||||
optalias_check(2, (const char *const *) tmp_argv, 0, &return_argc,
|
||||
|
||||
@@ -54,12 +54,9 @@ Please visit our Website: http://www.httrack.com
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct hostent FAR t_hostent;
|
||||
|
||||
#else
|
||||
#define HTS_USESCOPEID
|
||||
#define INVALID_SOCKET -1
|
||||
typedef struct hostent t_hostent;
|
||||
#endif
|
||||
|
||||
#if HTS_USEOPENSSL
|
||||
|
||||
@@ -77,40 +77,25 @@ HTSEXT_API T_SOC catch_url_init_std(int *port_prox, char *adr_prox) {
|
||||
// 1- Init the URL catcher
|
||||
|
||||
// catch_url_init(&port,&return_host);
|
||||
HTSEXT_API T_SOC catch_url_init(int *port, char *adr) {
|
||||
HTSEXT_API T_SOC catch_url_init(int *port, /* 128 bytes */ char *adr) {
|
||||
T_SOC soc = INVALID_SOCKET;
|
||||
char h_loc[256 + 2];
|
||||
char h_loc[256];
|
||||
|
||||
if (gethostname(h_loc, 256) == 0) { // host name
|
||||
if (gethostname(h_loc, sizeof(h_loc)) == 0) { // host name
|
||||
SOCaddr server;
|
||||
int server_size = sizeof(server);
|
||||
t_hostent *hp_loc;
|
||||
t_fullhostent buffer;
|
||||
|
||||
// effacer structure
|
||||
memset(&server, 0, sizeof(server));
|
||||
|
||||
if ((hp_loc = vxgethostbyname(h_loc, &buffer))) { // notre host
|
||||
|
||||
// copie adresse
|
||||
SOCaddr_copyaddr(server, server_size, hp_loc->h_addr_list[0],
|
||||
hp_loc->h_length);
|
||||
|
||||
if (hts_dns_resolve_nocache(h_loc, &server) != NULL) { // notre host
|
||||
if ((soc =
|
||||
(T_SOC) socket(SOCaddr_sinfamily(server), SOCK_STREAM,
|
||||
0)) != INVALID_SOCKET) {
|
||||
SOCaddr_initport(server, *port);
|
||||
if (bind(soc, (struct sockaddr *) &server, server_size) == 0) {
|
||||
if (bind(soc, &SOCaddr_sockaddr(server), SOCaddr_size(server)) == 0) {
|
||||
SOCaddr server2;
|
||||
SOClen len;
|
||||
SOClen len = SOCaddr_capacity(server2);
|
||||
|
||||
len = sizeof(server2);
|
||||
// effacer structure
|
||||
memset(&server2, 0, sizeof(server2));
|
||||
if (getsockname(soc, (struct sockaddr *) &server2, &len) == 0) {
|
||||
if (getsockname(soc, &SOCaddr_sockaddr(server2), &len) == 0) {
|
||||
*port = ntohs(SOCaddr_sinport(server)); // récupérer port
|
||||
if (listen(soc, 10) >= 0) { // au pif le 10
|
||||
SOCaddr_inetntoa(adr, 128, server2, len);
|
||||
if (listen(soc, 1) >= 0) {
|
||||
SOCaddr_inetntoa(adr, 128, server2);
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
closesocket(soc);
|
||||
@@ -168,15 +153,13 @@ HTSEXT_API int catch_url(T_SOC soc, char *url, char *method, char *data) {
|
||||
/* INFOS */
|
||||
{
|
||||
SOCaddr server2;
|
||||
SOClen len = sizeof(server2);
|
||||
SOClen len = SOCaddr_capacity(server2);
|
||||
|
||||
// effacer structure
|
||||
memset(&server2, 0, sizeof(server2));
|
||||
if (getpeername(soc, (struct sockaddr *) &server2, &len) == 0) {
|
||||
if (getpeername(soc, &SOCaddr_sockaddr(server2), &len) == 0) {
|
||||
char dot[256 + 2];
|
||||
|
||||
SOCaddr_inetntoa(dot, 256, server2, sizeof(server2));
|
||||
sprintf(url, "%s:%d", dot, htons(SOCaddr_sinport(server2)));
|
||||
SOCaddr_inetntoa(dot, sizeof(dot), server2);
|
||||
sprintf(url, "%s:%d", dot, ntohs(SOCaddr_sinport(server2)));
|
||||
}
|
||||
}
|
||||
/* INFOS */
|
||||
|
||||
@@ -966,24 +966,29 @@ char *hts_convertStringUTF8ToIDNA(const char *s, size_t size) {
|
||||
if (HTS_IS_LEADING_UTF8(c)) {
|
||||
/* commit sequence ? */
|
||||
if (utfSeq != (size_t) -1) {
|
||||
/* unicode character */
|
||||
punycode_uint uc = 0;
|
||||
|
||||
/* Reader: can read bytes up to j */
|
||||
#define RD ( utfSeq < j ? segData[utfSeq++] : -1 )
|
||||
|
||||
/* Writer: upon error, return FFFD (replacement character) */
|
||||
#define WR(C) uc = C != -1 ? (punycode_uint) C : (punycode_uint) 0xfffd
|
||||
#define WR(C) do { \
|
||||
if ((C) != -1) { \
|
||||
/* copy character */ \
|
||||
assertf(segOutputSize < segSize); \
|
||||
segInt[segOutputSize++] = (C); \
|
||||
} \
|
||||
/* In case of error, abort. */ \
|
||||
else { \
|
||||
FREE_BUFFER(); \
|
||||
return NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Read Unicode character. */
|
||||
/* Read/Write Unicode character. */
|
||||
READ_UNICODE(RD, WR);
|
||||
#undef RD
|
||||
#undef WR
|
||||
|
||||
/* copy character */
|
||||
assertf(segOutputSize < segSize);
|
||||
segInt[segOutputSize++] = uc;
|
||||
|
||||
/* not anymore in sequence */
|
||||
utfSeq = (size_t) -1;
|
||||
}
|
||||
|
||||
@@ -2355,7 +2355,7 @@ void host_ban(httrackp * opt, lien_url ** liens, int ptr, int lien_tot,
|
||||
if (strfield2(jump_identification(liens[i]->adr), host)) { // host
|
||||
hts_log_print(opt, LOG_DEBUG, "Cancel: %s%s", liens[i]->adr,
|
||||
liens[i]->fil);
|
||||
strcpybuff(liens[i]->adr, "!"); // cancel (invalide hash)
|
||||
hash_invalidate_entry(opt->hash, i); // invalidate hashtable entry
|
||||
// on efface pas le hash, because si on rencontre le lien, reverif sav..
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -232,7 +232,6 @@ struct t_hts_callback_ref {
|
||||
};
|
||||
|
||||
extern const t_hts_htmlcheck_callbacks default_callbacks;
|
||||
extern const t_hts_callback_ref default_callbacks_ref[];
|
||||
|
||||
#define HT_PRINT(A) strcatbuff(opt->state.HTbuff,A);
|
||||
#define HT_REQUEST_START opt->state.HTbuff[0]='\0';
|
||||
|
||||
80
src/htsftp.c
80
src/htsftp.c
@@ -147,16 +147,12 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
int timeout_onfly = 8; // attente réponse supplémentaire
|
||||
int transfer_list = 0; // directory
|
||||
int rest_understood = 0; // rest command understood
|
||||
t_fullhostent fullhostent_buffer; // buffer pour resolver
|
||||
|
||||
//
|
||||
T_SOC soc_ctl = INVALID_SOCKET;
|
||||
T_SOC soc_servdat = INVALID_SOCKET;
|
||||
T_SOC soc_dat = INVALID_SOCKET;
|
||||
|
||||
//
|
||||
SOCaddr server_data;
|
||||
int server_data_size = sizeof(server_data);
|
||||
|
||||
//
|
||||
line_retr[0] = adr_ip[0] = '\0';
|
||||
@@ -249,8 +245,6 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
// connexion
|
||||
{
|
||||
SOCaddr server;
|
||||
int server_size = sizeof(server);
|
||||
t_hostent *hp;
|
||||
char *a;
|
||||
char _adr[256];
|
||||
const char *error = "unknown error";
|
||||
@@ -270,8 +264,7 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
|
||||
// récupérer adresse résolue
|
||||
strcpybuff(back->info, "host name");
|
||||
hp = hts_gethostbyname2(opt, _adr, &fullhostent_buffer, &error);
|
||||
if (hp == NULL) {
|
||||
if (hts_dns_resolve2(opt, _adr, &server, &error) == NULL) {
|
||||
snprintf(back->r.msg, sizeof(back->r.msg),
|
||||
"Unable to get server's address: %s", error);
|
||||
// back->status=STATUS_FTP_READY; // fini
|
||||
@@ -280,12 +273,8 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
}
|
||||
_CHECK_HALT_FTP;
|
||||
|
||||
// copie adresse
|
||||
SOCaddr_copyaddr(server, server_size, hp->h_addr_list[0], hp->h_length);
|
||||
// copie adresse pour cnx data
|
||||
SOCaddr_copyaddr(server_data, server_data_size, hp->h_addr_list[0],
|
||||
hp->h_length);
|
||||
// memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
|
||||
SOCaddr_copy_SOCaddr(server_data, server);
|
||||
|
||||
// créer ("attachement") une socket (point d'accès) internet,en flot
|
||||
soc_ctl = (T_SOC) socket(SOCaddr_sinfamily(server), SOCK_STREAM, 0);
|
||||
@@ -302,12 +291,7 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
// connexion (bloquante, on est en thread)
|
||||
strcpybuff(back->info, "connect");
|
||||
|
||||
#ifdef _WIN32
|
||||
if (connect(soc_ctl, (const struct sockaddr FAR *) &server, server_size) !=
|
||||
0) {
|
||||
#else
|
||||
if (connect(soc_ctl, (struct sockaddr *) &server, server_size) == -1) {
|
||||
#endif
|
||||
if (connect(soc_ctl, &SOCaddr_sockaddr(server), SOCaddr_size(server)) != 0) {
|
||||
strcpybuff(back->r.msg, "Unable to connect to the server");
|
||||
// back->status=STATUS_FTP_READY; // fini
|
||||
back->r.statuscode = STATUSCODE_INVALID;
|
||||
@@ -419,7 +403,7 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
// Pré-REST
|
||||
//
|
||||
#if FTP_PASV
|
||||
if (SOCaddr_getproto(server, server_size) == '1') {
|
||||
if (SOCaddr_getproto(server) == '1') {
|
||||
strcpybuff(back->info, "pasv");
|
||||
snprintf(line, sizeof(line), "PASV");
|
||||
send_line(soc_ctl, line);
|
||||
@@ -581,7 +565,6 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
if (port_pasv) {
|
||||
SOCaddr server;
|
||||
int server_size = sizeof(server);
|
||||
t_hostent *hp;
|
||||
const char *error = "unknown error";
|
||||
|
||||
// effacer structure
|
||||
@@ -592,16 +575,9 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
|
||||
// résoudre
|
||||
if (adr_ip[0]) {
|
||||
hp = hts_gethostbyname2(opt, adr_ip, &fullhostent_buffer, &error);
|
||||
if (hp) {
|
||||
SOCaddr_copyaddr(server, server_size, hp->h_addr_list[0],
|
||||
hp->h_length);
|
||||
} else {
|
||||
server_size = 0;
|
||||
}
|
||||
hts_dns_resolve2(opt, adr_ip, &server, &error);
|
||||
} else {
|
||||
memcpy(&server, &server_data, sizeof(server_data));
|
||||
server_size = server_data_size;
|
||||
SOCaddr_copy_SOCaddr(server, server_data);
|
||||
}
|
||||
|
||||
// infos
|
||||
@@ -615,15 +591,7 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
if (soc_dat != INVALID_SOCKET) {
|
||||
// structure: connexion au domaine internet, port 80 (ou autre)
|
||||
SOCaddr_initport(server, port_pasv);
|
||||
// server.sin_port = htons((unsigned short int) port_pasv);
|
||||
#ifdef _WIN32
|
||||
if (connect
|
||||
(soc_dat, (const struct sockaddr FAR *) &server,
|
||||
server_size) == 0) {
|
||||
#else
|
||||
if (connect(soc_dat, (struct sockaddr *) &server, server_size) !=
|
||||
-1) {
|
||||
#endif
|
||||
if (connect(soc_dat, &SOCaddr_sockaddr(server), SOCaddr_size(server)) == 0) {
|
||||
strcpybuff(back->info, "retr");
|
||||
strcpybuff(line, line_retr);
|
||||
send_line(soc_ctl, line);
|
||||
@@ -856,33 +824,19 @@ T_SOC get_datasocket(char *to_send, size_t to_send_size) {
|
||||
to_send[0] = '\0';
|
||||
if (gethostname(h_loc, 256) == 0) { // host name
|
||||
SOCaddr server;
|
||||
int server_size = sizeof(server);
|
||||
t_hostent *hp_loc;
|
||||
t_fullhostent buffer;
|
||||
|
||||
// effacer structure
|
||||
memset(&server, 0, sizeof(server));
|
||||
|
||||
if ((hp_loc = vxgethostbyname(h_loc, &buffer))) { // notre host
|
||||
|
||||
// copie adresse
|
||||
SOCaddr_copyaddr(server, server_size, hp_loc->h_addr_list[0],
|
||||
hp_loc->h_length);
|
||||
|
||||
if (hts_dns_resolve_nocache(h_loc, &server) != NULL) { // notre host
|
||||
if ((soc =
|
||||
(T_SOC) socket(SOCaddr_sinfamily(server), SOCK_STREAM,
|
||||
0)) != INVALID_SOCKET) {
|
||||
|
||||
if (bind(soc, (struct sockaddr *) &server, server_size) == 0) {
|
||||
if (bind(soc, &SOCaddr_sockaddr(server), SOCaddr_size(server)) == 0) {
|
||||
SOCaddr server2;
|
||||
SOClen len;
|
||||
SOClen len = SOCaddr_capacity(server2);
|
||||
|
||||
len = sizeof(server2);
|
||||
// effacer structure
|
||||
memset(&server2, 0, sizeof(server2));
|
||||
if (getsockname(soc, (struct sockaddr *) &server2, &len) == 0) {
|
||||
if (getsockname(soc, &SOCaddr_sockaddr(server2), &len) == 0) {
|
||||
// *port=ntohs(server.sin_port); // récupérer port
|
||||
if (listen(soc, 10) >= 0) { // au pif le 10
|
||||
if (listen(soc, 1) >= 0) {
|
||||
#if HTS_INET6==0
|
||||
unsigned short int a, n1, n2;
|
||||
|
||||
@@ -895,7 +849,7 @@ T_SOC get_datasocket(char *to_send, size_t to_send_size) {
|
||||
char dot[256 + 2];
|
||||
char *a;
|
||||
|
||||
SOCaddr_inetntoa(dot, 256, server2, sizeof(server2));
|
||||
SOCaddr_inetntoa(dot, 256, server2);
|
||||
//
|
||||
dots[0] = '\0';
|
||||
strncatbuff(dots, dot, 128);
|
||||
@@ -913,9 +867,9 @@ T_SOC get_datasocket(char *to_send, size_t to_send_size) {
|
||||
{
|
||||
char dot[256 + 2];
|
||||
|
||||
SOCaddr_inetntoa(dot, 256, server2, len);
|
||||
SOCaddr_inetntoa(dot, 256, server2);
|
||||
snprintf(to_send, to_send_size, "EPRT |%c|%s|%d|",
|
||||
SOCaddr_getproto(server2, len), dot,
|
||||
SOCaddr_getproto(server2), dot,
|
||||
SOCaddr_sinport(server2));
|
||||
}
|
||||
#endif
|
||||
@@ -1093,7 +1047,7 @@ int check_socket(T_SOC soc) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
// poll!
|
||||
select(soc + 1, &fds, NULL, &fds_e, &tv);
|
||||
select((int) soc + 1, &fds, NULL, &fds_e, &tv);
|
||||
if (FD_ISSET(soc, &fds_e)) { // error detected
|
||||
return -1;
|
||||
} else if (FD_ISSET(soc, &fds)) {
|
||||
@@ -1116,7 +1070,7 @@ int check_socket_connect(T_SOC soc) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
// poll!
|
||||
select(soc + 1, NULL, &fds, &fds_e, &tv);
|
||||
select((int) soc + 1, NULL, &fds, &fds_e, &tv);
|
||||
if (FD_ISSET(soc, &fds_e)) { // error detected
|
||||
return -1;
|
||||
} else if (FD_ISSET(soc, &fds)) {
|
||||
|
||||
@@ -36,8 +36,8 @@ Please visit our Website: http://www.httrack.com
|
||||
#define HTTRACK_GLOBAL_DEFH
|
||||
|
||||
// Version (also check external version information)
|
||||
#define HTTRACK_VERSION "3.48-6"
|
||||
#define HTTRACK_VERSIONID "3.48.6"
|
||||
#define HTTRACK_VERSION "3.48-9"
|
||||
#define HTTRACK_VERSIONID "3.48.9"
|
||||
#define HTTRACK_AFF_VERSION "3.x"
|
||||
#define HTTRACK_LIB_VERSION "2.0"
|
||||
|
||||
|
||||
@@ -85,6 +85,14 @@ static int key_sav_equals(void *arg, const char *a, const char *b) {
|
||||
return strcasecmp(a, b) == 0;
|
||||
}
|
||||
|
||||
static const char* key_sav_debug_print(void *arg, const char *a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
static const char* value_sav_debug_print(void *arg, void *a) {
|
||||
return (char*) a;
|
||||
}
|
||||
|
||||
/* Pseudo-key (lien_url structure) hash function */
|
||||
static inthash_keys key_adrfil_hashes_generic(void *arg, const char *value_,
|
||||
const int former) {
|
||||
@@ -151,6 +159,31 @@ static int key_adrfil_equals_generic(void *arg, const char *a_, const char *b_,
|
||||
}
|
||||
}
|
||||
|
||||
static const char* key_adrfil_debug_print_(void *arg, const char *a_, const int former) {
|
||||
hash_struct *const hash = (hash_struct*) arg;
|
||||
const lien_url*const a = (lien_url*) a_;
|
||||
const char *const a_adr = !former ? a->adr : a->former_adr;
|
||||
const char *const a_fil = !former ? a->fil : a->former_fil;
|
||||
snprintf(hash->normfil, sizeof(hash->normfil), "%s%s", a_adr, a_fil);
|
||||
return hash->normfil;
|
||||
}
|
||||
|
||||
static const char* key_adrfil_debug_print(void *arg, const char *a_) {
|
||||
return key_adrfil_debug_print_(arg, a_, 0);
|
||||
}
|
||||
|
||||
static const char* key_former_adrfil_debug_print(void *arg, const char *a_) {
|
||||
return key_adrfil_debug_print_(arg, a_, 1);
|
||||
}
|
||||
|
||||
static const char* value_adrfil_debug_print(void *arg, void *value) {
|
||||
hash_struct *const hash = (hash_struct*) arg;
|
||||
inthash_value v;
|
||||
v.ptr = value;
|
||||
snprintf(hash->normfil2, sizeof(hash->normfil2), "%d", (int) v.intg);
|
||||
return hash->normfil2;
|
||||
}
|
||||
|
||||
/* "adr"/"fil" lien_url structure members hashing function */
|
||||
static inthash_keys key_adrfil_hashes(void *arg, const char *value_) {
|
||||
return key_adrfil_hashes_generic(arg, value_, 0);
|
||||
@@ -207,6 +240,20 @@ void hash_init(httrackp *opt, hash_struct * hash, int normalized) {
|
||||
key_former_adrfil_hashes,
|
||||
key_former_adrfil_equals,
|
||||
hash);
|
||||
|
||||
/* pretty-printing */
|
||||
inthash_set_print_handler(hash->sav,
|
||||
key_sav_debug_print,
|
||||
value_sav_debug_print,
|
||||
NULL);
|
||||
inthash_set_print_handler(hash->adrfil,
|
||||
key_adrfil_debug_print,
|
||||
value_adrfil_debug_print,
|
||||
hash);
|
||||
inthash_set_print_handler(hash->former_adrfil,
|
||||
key_former_adrfil_debug_print,
|
||||
value_adrfil_debug_print,
|
||||
hash);
|
||||
}
|
||||
|
||||
void hash_free(hash_struct *hash) {
|
||||
@@ -272,3 +319,14 @@ void hash_write(hash_struct * hash, int lpos) {
|
||||
inthash_write(hash->former_adrfil, (char*) hash->liens[lpos], lpos);
|
||||
}
|
||||
}
|
||||
|
||||
void hash_invalidate_entry(hash_struct * hash, int lpos) {
|
||||
if (inthash_remove(hash->adrfil, (char*) hash->liens[lpos])) {
|
||||
/* devalidate entry now it is removed from hashtable */
|
||||
strcpybuff(hash->liens[lpos]->adr, "!");
|
||||
/* add back */
|
||||
inthash_write(hash->adrfil, (char*) hash->liens[lpos], lpos);
|
||||
} else {
|
||||
assertf(! "error invalidating hash entry");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ void hash_free(hash_struct *hash);
|
||||
int hash_read(const hash_struct * hash, const char *nom1, const char *nom2,
|
||||
hash_struct_type type);
|
||||
void hash_write(hash_struct * hash, int lpos);
|
||||
void hash_invalidate_entry(hash_struct * hash, int lpos);
|
||||
int *hash_calc_chaine(hash_struct * hash, hash_struct_type type, int pos);
|
||||
unsigned long int hash_cle(const char *nom1, const char *nom2);
|
||||
#endif
|
||||
|
||||
@@ -187,6 +187,16 @@ struct struct_inthash {
|
||||
/** hashtable name for logging **/
|
||||
const char *name;
|
||||
} error;
|
||||
|
||||
/** How to handle pretty-print (debug) (might be NULL). **/
|
||||
struct {
|
||||
/** key print() **/
|
||||
t_inthash_printkeyhandler key;
|
||||
/** value print() **/
|
||||
t_inthash_printvaluehandler value;
|
||||
/** opaque argument **/
|
||||
void *arg;
|
||||
} print;
|
||||
} custom;
|
||||
};
|
||||
|
||||
@@ -889,10 +899,62 @@ static int inthash_add_item_(inthash hashtable, inthash_item item) {
|
||||
(int) hashtable->stash.size);
|
||||
return 1; /* added */
|
||||
} else {
|
||||
/* debugging */
|
||||
if (hashtable->custom.print.key != NULL
|
||||
&& hashtable->custom.print.value != NULL) {
|
||||
size_t i;
|
||||
for(i = 0 ; i < hashtable->stash.size ; i++) {
|
||||
inthash_item *const item = &hashtable->stash.items[i];
|
||||
const size_t pos1 = inthash_hash_to_pos(hashtable, item->hashes.hash1);
|
||||
const size_t pos2 = inthash_hash_to_pos(hashtable, item->hashes.hash2);
|
||||
inthash_crit(hashtable,
|
||||
"stash[%u]: key='%s' value='%s' pos1=%d pos2=%d hash1=%04x hash2=%04x",
|
||||
(int) i,
|
||||
hashtable->custom.print.key(hashtable->custom.print.arg, item->name),
|
||||
hashtable->custom.print.value(hashtable->custom.print.arg, item->value.ptr),
|
||||
(int) pos1, (int) pos2,
|
||||
item->hashes.hash1, item->hashes.hash2);
|
||||
if (!inthash_is_free(hashtable, pos1)) {
|
||||
inthash_item *const item = &hashtable->items[pos1];
|
||||
const size_t pos1 = inthash_hash_to_pos(hashtable, item->hashes.hash1);
|
||||
const size_t pos2 = inthash_hash_to_pos(hashtable, item->hashes.hash2);
|
||||
inthash_crit(hashtable,
|
||||
"\t.. collisionning with key='%s' value='%s' pos1=%d pos2=%d hash1=%04x hash2=%04x",
|
||||
hashtable->custom.print.key(hashtable->custom.print.arg, item->name),
|
||||
hashtable->custom.print.value(hashtable->custom.print.arg, item->value.ptr),
|
||||
(int) pos1, (int) pos2,
|
||||
item->hashes.hash1, item->hashes.hash2);
|
||||
} else {
|
||||
inthash_crit(hashtable, "\t.. collisionning with a free slot (%d)!", (int) pos1);
|
||||
}
|
||||
if (!inthash_is_free(hashtable, pos2)) {
|
||||
inthash_item *const item = &hashtable->items[pos2];
|
||||
const size_t pos1 = inthash_hash_to_pos(hashtable, item->hashes.hash1);
|
||||
const size_t pos2 = inthash_hash_to_pos(hashtable, item->hashes.hash2);
|
||||
inthash_crit(hashtable,
|
||||
"\t.. collisionning with key='%s' value='%s' pos1=%d pos2=%d hash1=%04x hash2=%04x",
|
||||
hashtable->custom.print.key(hashtable->custom.print.arg, item->name),
|
||||
hashtable->custom.print.value(hashtable->custom.print.arg, item->value.ptr),
|
||||
(int) pos1, (int) pos2,
|
||||
item->hashes.hash1, item->hashes.hash2);
|
||||
} else {
|
||||
inthash_crit(hashtable, "\t.. collisionning with a free slot (%d)!", (int) pos2);
|
||||
}
|
||||
}
|
||||
//struct_inthash_enum e = inthash_enum_new(hashtable);
|
||||
//while((item = inthash_enum_next(&e)) != NULL) {
|
||||
// inthash_crit(hashtable, "element key='%s' value='%s' hash1=%04x hash2=%04x",
|
||||
// hashtable->custom.print.key(hashtable->custom.print.arg, item->name),
|
||||
// hashtable->custom.print.value(hashtable->custom.print.arg, item->value.ptr),
|
||||
// item->hashes.hash1, item->hashes.hash2);
|
||||
//}
|
||||
}
|
||||
|
||||
/* we are doomed. hopefully the probability is lower than being killed
|
||||
by a wandering radioactive monkey */
|
||||
inthash_log_stats(hashtable);
|
||||
inthash_assert(hashtable, ! "hashtable internal error: cuckoo/stash collision");
|
||||
|
||||
/* not reachable code */
|
||||
return -1;
|
||||
}
|
||||
@@ -934,7 +996,7 @@ int inthash_write_value(inthash hashtable, const char *name,
|
||||
inthash_warning(hashtable,
|
||||
"stash size still full despite %"UINT_64_FORMAT
|
||||
" elements used out of %"UINT_64_FORMAT,
|
||||
hashtable->used, half_size*2);
|
||||
(uint64_t) hashtable->used, (uint64_t) half_size*2);
|
||||
}
|
||||
|
||||
/* statistics */
|
||||
@@ -1235,9 +1297,13 @@ inthash inthash_new(size_t initial_size) {
|
||||
hashtable->custom.key.hash = NULL;
|
||||
hashtable->custom.key.equals = NULL;
|
||||
hashtable->custom.key.arg = NULL;
|
||||
hashtable->custom.error.log = NULL;
|
||||
hashtable->custom.error.fatal = NULL;
|
||||
hashtable->custom.error.name = NULL;
|
||||
hashtable->custom.error.arg = NULL;
|
||||
hashtable->custom.print.key = NULL;
|
||||
hashtable->custom.print.value = NULL;
|
||||
hashtable->custom.print.arg = NULL;
|
||||
}
|
||||
return hashtable;
|
||||
}
|
||||
@@ -1288,12 +1354,20 @@ void inthash_set_assert_handler(inthash hashtable,
|
||||
t_inthash_loghandler log,
|
||||
t_inthash_asserthandler fatal,
|
||||
void *arg) {
|
||||
inthash_assert(hashtable, fatal != NULL);
|
||||
hashtable->custom.error.log = log;
|
||||
hashtable->custom.error.fatal = fatal;
|
||||
hashtable->custom.error.arg = arg;
|
||||
}
|
||||
|
||||
void inthash_set_print_handler(inthash hashtable,
|
||||
t_inthash_printkeyhandler key,
|
||||
t_inthash_printvaluehandler value,
|
||||
void *arg) {
|
||||
hashtable->custom.print.key = key;
|
||||
hashtable->custom.print.value = value;
|
||||
hashtable->custom.print.arg = arg;
|
||||
}
|
||||
|
||||
size_t inthash_nitems(inthash hashtable) {
|
||||
if (hashtable != NULL)
|
||||
return hashtable->used;
|
||||
|
||||
@@ -67,6 +67,7 @@ typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
/** Value. **/
|
||||
typedef union inthash_value {
|
||||
@@ -140,6 +141,12 @@ typedef void (*t_inthash_loghandler)(void *arg, inthash_loglevel level,
|
||||
/** Hashtable fatal assertion failure. **/
|
||||
typedef void (*t_inthash_asserthandler)(void *arg, const char* exp, const char* file, int line);
|
||||
|
||||
/** Key printer (debug) **/
|
||||
typedef const char* (*t_inthash_printkeyhandler)(void *arg, const char *name);
|
||||
|
||||
/** Value printer (debug) **/
|
||||
typedef const char* (*t_inthash_printvaluehandler)(void *arg, void *value);
|
||||
|
||||
/**
|
||||
* Value comparison handler (returns non-zero value if strings are equal).
|
||||
**/
|
||||
@@ -240,6 +247,18 @@ void inthash_set_assert_handler(inthash hashtable,
|
||||
t_inthash_asserthandler fatal,
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* Set pretty print loggers (debug). Both handlers must return a string
|
||||
* pointer which shall be valid until the next call. Both key and value
|
||||
* pointers shall be valid at the same time.
|
||||
* name: handler called to print the string representation of the name
|
||||
* value: handler called to print the string representation of the value
|
||||
**/
|
||||
void inthash_set_print_handler(inthash hashtable,
|
||||
t_inthash_printkeyhandler key,
|
||||
t_inthash_printvaluehandler value,
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* Set the hashtable name, for degugging purpose.
|
||||
* name: the hashtable name (ASCII or UTF-8)
|
||||
|
||||
387
src/htslib.c
387
src/htslib.c
@@ -62,6 +62,7 @@ Please visit our Website: http://www.httrack.com
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@@ -83,6 +84,13 @@ static long int timezone = 0;
|
||||
#include <sys/stat.h>
|
||||
/* END specific definitions */
|
||||
|
||||
/* Windows might be missing va_copy */
|
||||
#ifdef _WIN32
|
||||
#ifndef va_copy
|
||||
#define va_copy(dst, src) ((dst) = (src))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Debugging
|
||||
#if _HTS_WIDE
|
||||
FILE *DEBUG_fp = NULL;
|
||||
@@ -2118,27 +2126,16 @@ htsblk http_test(httrackp * opt, char *adr, char *fil, char *loc) {
|
||||
// peut ouvrir avec des connect() non bloquants: waitconnect=0/1
|
||||
T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
|
||||
int waitconnect) {
|
||||
t_fullhostent fullhostent_buffer; // buffer pour resolver
|
||||
T_SOC soc; // descipteur de la socket
|
||||
char *iadr;
|
||||
|
||||
// unsigned short int port;
|
||||
|
||||
// si iadr="#" alors c'est une fausse URL, mais un vrai fichier
|
||||
// local.
|
||||
// utile pour les tests!
|
||||
//## if (iadr[0]!=lOCAL_CHAR) {
|
||||
if (strcmp(_iadr, "file://") != 0) { /* non fichier */
|
||||
SOCaddr server;
|
||||
int server_size = sizeof(server);
|
||||
t_hostent *hp;
|
||||
const char *error = "unknown error";
|
||||
|
||||
// effacer structure
|
||||
memset(&server, 0, sizeof(server));
|
||||
|
||||
// tester un éventuel id:pass et virer id:pass@ si détecté
|
||||
iadr = jump_identification(_iadr);
|
||||
const char *const iadr = jump_identification(_iadr);
|
||||
|
||||
SOCaddr_clear(server);
|
||||
|
||||
#if HDEBUG
|
||||
printf("gethostbyname\n");
|
||||
@@ -2156,7 +2153,8 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
|
||||
#else
|
||||
port = 80; // port par défaut
|
||||
#endif
|
||||
if (a) {
|
||||
|
||||
if (a != NULL) {
|
||||
char BIGSTK iadr2[HTS_URLMAXSIZE * 2];
|
||||
int i = -1;
|
||||
|
||||
@@ -2165,25 +2163,24 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
|
||||
if (i != -1) {
|
||||
port = (unsigned short int) i;
|
||||
}
|
||||
|
||||
// adresse véritable (sans :xx)
|
||||
strncatbuff(iadr2, iadr, (int) (a - iadr));
|
||||
|
||||
// adresse sans le :xx
|
||||
hp = hts_gethostbyname2(opt, iadr2, &fullhostent_buffer, &error);
|
||||
hts_dns_resolve2(opt, iadr2, &server, &error);
|
||||
|
||||
} else {
|
||||
|
||||
// adresse normale (port par défaut par la suite)
|
||||
hp = hts_gethostbyname2(opt, iadr, &fullhostent_buffer, &error);
|
||||
hts_dns_resolve2(opt, iadr, &server, &error);
|
||||
}
|
||||
|
||||
} else // port défini
|
||||
hp = hts_gethostbyname2(opt, iadr, &fullhostent_buffer, &error);
|
||||
} else { // port défini
|
||||
hts_dns_resolve2(opt, iadr, &server, &error);
|
||||
}
|
||||
|
||||
// Conversion iadr -> adresse
|
||||
// structure recevant le nom de l'hôte, etc
|
||||
//struct hostent *hp;
|
||||
if (hp == NULL) {
|
||||
if (!SOCaddr_is_valid(server)) {
|
||||
#if DEBUG
|
||||
printf("erreur gethostbyname\n");
|
||||
#endif
|
||||
@@ -2198,13 +2195,10 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
|
||||
}
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
// copie adresse
|
||||
SOCaddr_copyaddr(server, server_size, hp->h_addr_list[0], hp->h_length);
|
||||
|
||||
// make a copy for external clients
|
||||
retour->address_size = sizeof(retour->address);
|
||||
SOCaddr_copyaddr(retour->address, retour->address_size, hp->h_addr_list[0],
|
||||
hp->h_length);
|
||||
// memcpy(&SOCaddr_sinaddr(server), hp->h_addr_list[0], hp->h_length);
|
||||
SOCaddr_copy_SOCaddr(retour->address, server);
|
||||
retour->address_size = SOCaddr_size(retour->address);
|
||||
|
||||
// créer ("attachement") une socket (point d'accès) internet,en flot
|
||||
#if HDEBUG
|
||||
@@ -2238,14 +2232,13 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
|
||||
}
|
||||
// bind this address
|
||||
if (retour != NULL && strnotempty(retour->req.proxy.bindhost)) {
|
||||
t_fullhostent bind_buffer;
|
||||
const char *error = "unknown error";
|
||||
SOCaddr bind_addr;
|
||||
|
||||
hp = hts_gethostbyname2(opt, retour->req.proxy.bindhost, &bind_buffer,
|
||||
&error);
|
||||
if (hp == NULL
|
||||
|| bind(soc, (struct sockaddr *) hp->h_addr_list[0],
|
||||
hp->h_length) != 0) {
|
||||
if (hts_dns_resolve2(opt, retour->req.proxy.bindhost,
|
||||
&bind_addr, &error) == NULL
|
||||
|| bind(soc, &SOCaddr_sockaddr(bind_addr),
|
||||
SOCaddr_size(bind_addr)) != 0) {
|
||||
if (retour && retour->msg) {
|
||||
#ifdef _WIN32
|
||||
snprintf(retour->msg, sizeof(retour->msg),
|
||||
@@ -2297,25 +2290,20 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
|
||||
#if HTS_WIDE_DEBUG
|
||||
DEBUG_W("connect\n");
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
if (connect(soc, (const struct sockaddr FAR *) &server, server_size) != 0) {
|
||||
#else
|
||||
if (connect(soc, (struct sockaddr *) &server, server_size) == -1) {
|
||||
#endif
|
||||
|
||||
if (connect(soc, &SOCaddr_sockaddr(server), SOCaddr_size(server)) != 0) {
|
||||
// bloquant
|
||||
if (waitconnect) {
|
||||
#if HDEBUG
|
||||
printf("unable to connect!\n");
|
||||
#endif
|
||||
if (retour && retour->msg) {
|
||||
if (retour != NULL && retour->msg) {
|
||||
#ifdef _WIN32
|
||||
int last_errno = WSAGetLastError();
|
||||
const int last_errno = WSAGetLastError();
|
||||
|
||||
sprintf(retour->msg, "Unable to connect to the server: %s",
|
||||
strerror(last_errno));
|
||||
#else
|
||||
int last_errno = errno;
|
||||
const int last_errno = errno;
|
||||
|
||||
sprintf(retour->msg, "Unable to connect to the server: %s",
|
||||
strerror(last_errno));
|
||||
@@ -2983,7 +2971,7 @@ int sendc(htsblk * r, const char *s) {
|
||||
}
|
||||
|
||||
// Remplace read
|
||||
int finput(int fd, char *s, int max) {
|
||||
int finput(T_SOC fd, char *s, int max) {
|
||||
char c;
|
||||
int j = 0;
|
||||
|
||||
@@ -4411,8 +4399,10 @@ HTSEXT_API char *hts_rootdir(char *file) {
|
||||
strc.path[0] = '\0';
|
||||
strc.init = 1;
|
||||
if (strnotempty(file)) {
|
||||
const size_t file_len = strlen(file);
|
||||
char *a;
|
||||
|
||||
assertf(file_len < sizeof(strc.path));
|
||||
strcpybuff(strc.path, file);
|
||||
while((a = strrchr(strc.path, '\\')))
|
||||
*a = '/';
|
||||
@@ -4422,7 +4412,7 @@ HTSEXT_API char *hts_rootdir(char *file) {
|
||||
strc.path[0] = '\0';
|
||||
}
|
||||
if (!strnotempty(strc.path)) {
|
||||
if (getcwd(strc.path, 1024) == NULL)
|
||||
if (getcwd(strc.path, sizeof(strc.path)) == NULL)
|
||||
strc.path[0] = '\0';
|
||||
else
|
||||
strcatbuff(strc.path, "/");
|
||||
@@ -4558,7 +4548,6 @@ int hts_read(htsblk * r, char *buff, int size) {
|
||||
|
||||
// -- Gestion cache DNS --
|
||||
// 'RX98
|
||||
#if HTS_DNSCACHE
|
||||
|
||||
// 'capsule' contenant uniquement le cache
|
||||
t_dnscache *_hts_cache(httrackp * opt) {
|
||||
@@ -4592,63 +4581,47 @@ void hts_cache_free(t_dnscache *const root) {
|
||||
// routine pour le cache - retour optionnel à donner à chaque fois
|
||||
// NULL: nom non encore testé dans le cache
|
||||
// si h_length==0 alors le nom n'existe pas dans le dns
|
||||
static t_hostent *hts_ghbn(const t_dnscache *cache, const char *const iadr, t_hostent *retour) {
|
||||
static SOCaddr* hts_ghbn(const t_dnscache *cache, const char *const iadr, SOCaddr *const addr) {
|
||||
assertf(addr != NULL);
|
||||
for(; cache != NULL; cache = cache->n) {
|
||||
assertf(cache != NULL);
|
||||
assertf(iadr != NULL);
|
||||
if (cache->iadr != NULL && strcmp(cache->iadr, iadr) == 0) { // ok trouvé
|
||||
if (cache->host_length > 0) { // entrée valide
|
||||
if (retour->h_addr_list[0])
|
||||
memcpy(retour->h_addr_list[0], cache->host_addr, cache->host_length);
|
||||
retour->h_length = cache->host_length;
|
||||
SOCaddr_copyaddr2(*addr, cache->host_addr, cache->host_length);
|
||||
return addr;
|
||||
} else if (cache->host_length == 0) { // en cours
|
||||
return NULL;
|
||||
} else { // erreur dans le dns, déja vérifié
|
||||
if (retour->h_addr_list[0])
|
||||
retour->h_addr_list[0][0] = '\0';
|
||||
retour->h_length = 0; // erreur, n'existe pas
|
||||
SOCaddr_clear(*addr);
|
||||
return addr;
|
||||
}
|
||||
return retour;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static t_hostent *vxgethostbyname2_(const char *const hostname,
|
||||
void *const v_buffer, const char **error) {
|
||||
t_fullhostent *buffer = (t_fullhostent *) v_buffer;
|
||||
|
||||
/* Clear */
|
||||
fullhostent_init(buffer);
|
||||
|
||||
static SOCaddr* hts_dns_resolve_nocache2_(const char *const hostname,
|
||||
SOCaddr *const addr,
|
||||
const char **error) {
|
||||
{
|
||||
#if HTS_INET6==0
|
||||
/*
|
||||
ipV4 resolver
|
||||
*/
|
||||
t_hostent *hp = gethostbyname(hostname);
|
||||
/* IPv4 resolver */
|
||||
struct hostent *const hp = gethostbyname(hostname);
|
||||
|
||||
if (hp != NULL) {
|
||||
if ((hp->h_length)
|
||||
&& (((unsigned int) hp->h_length) <= buffer->addr_maxlen)) {
|
||||
memcpy(buffer->hp.h_addr_list[0], hp->h_addr_list[0], hp->h_length);
|
||||
buffer->hp.h_length = hp->h_length;
|
||||
return &(buffer->hp);
|
||||
}
|
||||
SOCaddr_copyaddr2(addr, hp->h_addr_list[0], hp->h_length);
|
||||
return SOCaddr_is_valid(addr) ? &addr : NULL;
|
||||
} else {
|
||||
SOCaddr_clear(*addr);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
ipV6 resolver
|
||||
*/
|
||||
/*
|
||||
int error_num=0;
|
||||
t_hostent* hp=getipnodebyname(hostname, AF_INET6, AI_DEFAULT, &error_num);
|
||||
oops, deprecated :(
|
||||
*/
|
||||
/* IPv6 resolver */
|
||||
struct addrinfo *res = NULL;
|
||||
struct addrinfo hints;
|
||||
int gerr;
|
||||
|
||||
SOCaddr_clear(*addr);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
if (IPV6_resolver == 1) // V4 only (for bogus V6 entries)
|
||||
hints.ai_family = PF_INET;
|
||||
@@ -4659,13 +4632,9 @@ static t_hostent *vxgethostbyname2_(const char *const hostname,
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
if ( ( gerr = getaddrinfo(hostname, NULL, &hints, &res) ) == 0) {
|
||||
if (res) {
|
||||
if ((res->ai_addr) && (res->ai_addrlen)
|
||||
&& (res->ai_addrlen <= buffer->addr_maxlen)) {
|
||||
memcpy(buffer->hp.h_addr_list[0], res->ai_addr, res->ai_addrlen);
|
||||
buffer->hp.h_length = (short) res->ai_addrlen;
|
||||
freeaddrinfo(res);
|
||||
return &(buffer->hp);
|
||||
if (res != NULL) {
|
||||
if (res->ai_addr != NULL && res->ai_addrlen != 0) {
|
||||
SOCaddr_copyaddr2(*addr, res->ai_addr, res->ai_addrlen);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -4678,11 +4647,12 @@ static t_hostent *vxgethostbyname2_(const char *const hostname,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
|
||||
return SOCaddr_is_valid(*addr) ? addr : NULL;
|
||||
}
|
||||
|
||||
HTSEXT_API t_hostent *vxgethostbyname2(const char *const hostname,
|
||||
void *const v_buffer, const char **error) {
|
||||
HTSEXT_API SOCaddr* hts_dns_resolve_nocache2(const char *const hostname,
|
||||
SOCaddr *const addr, const char **error) {
|
||||
/* Protection */
|
||||
if (!strnotempty(hostname)) {
|
||||
return NULL;
|
||||
@@ -4693,43 +4663,40 @@ HTSEXT_API t_hostent *vxgethostbyname2(const char *const hostname,
|
||||
The resolver doesn't seem to handle IP6 addresses in brackets
|
||||
*/
|
||||
if ((hostname[0] == '[') && (hostname[strlen(hostname) - 1] == ']')) {
|
||||
t_hostent *ret;
|
||||
SOCaddr *ret;
|
||||
size_t size = strlen(hostname);
|
||||
char *copy = malloct(size + 1);
|
||||
assertf(copy != NULL);
|
||||
copy[0] = '\0';
|
||||
strncat(copy, hostname + 1, size - 2);
|
||||
ret = vxgethostbyname2_(copy, v_buffer, error);
|
||||
ret = hts_dns_resolve_nocache2_(copy, addr, error);
|
||||
freet(copy);
|
||||
return ret;
|
||||
} else {
|
||||
return vxgethostbyname2_(hostname, v_buffer, error);
|
||||
return hts_dns_resolve_nocache2_(hostname, addr, error);
|
||||
}
|
||||
}
|
||||
|
||||
HTSEXT_API t_hostent *vxgethostbyname(const char *const hostname, void *v_buffer) {
|
||||
return vxgethostbyname2(hostname, v_buffer, NULL);
|
||||
HTSEXT_API SOCaddr* hts_dns_resolve_nocache(const char *const hostname, SOCaddr *const addr) {
|
||||
return hts_dns_resolve_nocache2(hostname, addr, NULL);
|
||||
}
|
||||
|
||||
HTSEXT_API int check_hostname_dns(const char *const hostname) {
|
||||
t_fullhostent buffer;
|
||||
return vxgethostbyname(hostname, &buffer) != NULL;
|
||||
SOCaddr buffer;
|
||||
return hts_dns_resolve_nocache(hostname, &buffer) != NULL;
|
||||
}
|
||||
|
||||
// Needs locking
|
||||
// cache dns interne à HTS // ** FREE A FAIRE sur la chaine
|
||||
static t_hostent *hts_gethostbyname_(httrackp * opt, const char *_iadr, void *v_buffer, const char **error) {
|
||||
static SOCaddr* hts_dns_resolve_(httrackp * opt, const char *_iadr,
|
||||
SOCaddr *const addr, const char **error) {
|
||||
char BIGSTK iadr[HTS_URLMAXSIZE * 2];
|
||||
t_fullhostent *buffer = (t_fullhostent *) v_buffer;
|
||||
t_dnscache *cache = _hts_cache(opt); // adresse du cache
|
||||
t_hostent *hp;
|
||||
SOCaddr *sa;
|
||||
|
||||
assertf(opt != NULL);
|
||||
assertf(_iadr != NULL);
|
||||
assertf(v_buffer != NULL);
|
||||
|
||||
/* Clear */
|
||||
fullhostent_init(buffer);
|
||||
assertf(addr != NULL);
|
||||
|
||||
strcpybuff(iadr, jump_identification(_iadr));
|
||||
// couper éventuel :
|
||||
@@ -4741,92 +4708,56 @@ static t_hostent *hts_gethostbyname_(httrackp * opt, const char *_iadr, void *v_
|
||||
}
|
||||
|
||||
/* get IP from the dns cache */
|
||||
hp = hts_ghbn(cache, iadr, &buffer->hp);
|
||||
if (hp) {
|
||||
if (hp->h_length > 0)
|
||||
return hp;
|
||||
else
|
||||
return NULL; // entrée erronée (erreur DNS) dans le DNS
|
||||
sa = hts_ghbn(cache, iadr, addr);
|
||||
if (sa != NULL) {
|
||||
return SOCaddr_is_valid(*sa) ? sa : NULL;
|
||||
} else { // non présent dans le cache dns, tester
|
||||
// find queue
|
||||
for(; cache->n != NULL; cache = cache->n) ;
|
||||
|
||||
#if HTS_WIDE_DEBUG
|
||||
DEBUG_W("gethostbyname\n");
|
||||
#endif
|
||||
#if HDEBUG
|
||||
printf("gethostbyname (not in cache)\n");
|
||||
#endif
|
||||
{
|
||||
unsigned long inetaddr;
|
||||
|
||||
#ifdef _WIN32
|
||||
if ((inetaddr = inet_addr(iadr)) == INADDR_NONE) {
|
||||
#else
|
||||
if ((inetaddr = inet_addr(iadr)) == (in_addr_t) - 1) {
|
||||
#endif
|
||||
#if DEBUGDNS
|
||||
printf("resolving (not cached) %s\n", iadr);
|
||||
printf("resolving (not cached) %s\n", iadr);
|
||||
#endif
|
||||
hp = vxgethostbyname2(iadr, buffer, error); // calculer IP host
|
||||
} else { // numérique, convertir sans passer par le dns
|
||||
buffer->hp.h_addr_list[0] = (char *) &inetaddr;
|
||||
buffer->hp.h_length = 4;
|
||||
hp = &buffer->hp;
|
||||
}
|
||||
}
|
||||
|
||||
sa = hts_dns_resolve_nocache2(iadr, addr, error); // calculer IP host
|
||||
|
||||
#if HTS_WIDE_DEBUG
|
||||
DEBUG_W("gethostbyname done\n");
|
||||
#endif
|
||||
|
||||
/* attempt to store new entry */
|
||||
cache->n = (t_dnscache *) calloct(1, sizeof(t_dnscache));
|
||||
if (cache->n != NULL) {
|
||||
strcpybuff(cache->n->iadr, iadr);
|
||||
if (hp != NULL) {
|
||||
memcpy(cache->n->host_addr, hp->h_addr_list[0], hp->h_length);
|
||||
cache->n->host_length = hp->h_length;
|
||||
if (sa != NULL) {
|
||||
cache->n->host_length = SOCaddr_size(*sa);
|
||||
assertf(cache->n->host_length < sizeof(cache->n->host_addr));
|
||||
memcpy(cache->n->host_addr, &SOCaddr_sockaddr(*sa), cache->n->host_length);
|
||||
} else {
|
||||
cache->n->host_addr[0] = '\0';
|
||||
cache->n->host_length = 0; // non existant dans le dns
|
||||
}
|
||||
cache->n->n = NULL;
|
||||
return hp;
|
||||
} else { // on peut pas noter, mais on peut renvoyer le résultat
|
||||
return hp;
|
||||
return sa;
|
||||
}
|
||||
|
||||
/* return result if any */
|
||||
return sa;
|
||||
} // retour hp du cache
|
||||
}
|
||||
|
||||
t_hostent *hts_gethostbyname2(httrackp * opt, const char *_iadr, void *v_buffer, const char **error) {
|
||||
t_hostent *ret;
|
||||
SOCaddr* hts_dns_resolve2(httrackp * opt, const char *_iadr, SOCaddr *const addr, const char **error) {
|
||||
SOCaddr *ret;
|
||||
hts_mutexlock(&opt->state.lock);
|
||||
ret = hts_gethostbyname_(opt, _iadr, v_buffer, error);
|
||||
ret = hts_dns_resolve_(opt, _iadr, addr, error);
|
||||
hts_mutexrelease(&opt->state.lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
t_hostent *hts_gethostbyname(httrackp * opt, const char *_iadr, void *v_buffer) {
|
||||
return hts_gethostbyname2(opt ,_iadr, v_buffer, NULL);
|
||||
SOCaddr* hts_dns_resolve(httrackp * opt, const char *_iadr, SOCaddr *const addr) {
|
||||
return hts_dns_resolve2(opt, _iadr, addr, NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
static HTS_INLINE t_hostent *hts_gethostbyname(httrackp * opt, char *iadr,
|
||||
t_fullhostent * buffer) {
|
||||
t_hostent *retour;
|
||||
|
||||
#if HTS_WIDE_DEBUG
|
||||
DEBUG_W("gethostbyname (2)\n");
|
||||
#endif
|
||||
#if DEBUGDNS
|
||||
printf("blocking method gethostbyname() in progress for %s\n", iadr);
|
||||
#endif
|
||||
retour = vxgethostbyname(jump_identification(iadr),);
|
||||
#if HTS_WIDE_DEBUG
|
||||
DEBUG_W("gethostbyname (2) done\n");
|
||||
#endif
|
||||
return retour;
|
||||
}
|
||||
#endif
|
||||
|
||||
// --- Tracage des mallocs() ---
|
||||
#ifdef HTS_TRACE_MALLOC
|
||||
//#define htsLocker(A, N) htsLocker(A, N)
|
||||
@@ -5112,6 +5043,17 @@ static int ssl_vulnerable(const char *version) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* user abort callback */
|
||||
htsErrorCallback htsCallbackErr = NULL;
|
||||
|
||||
HTSEXT_API void hts_set_error_callback(htsErrorCallback handler) {
|
||||
htsCallbackErr = handler;
|
||||
}
|
||||
|
||||
HTSEXT_API htsErrorCallback hts_get_error_callback() {
|
||||
return htsCallbackErr;
|
||||
}
|
||||
|
||||
static void default_inthash_asserthandler(void *arg, const char* exp, const char* file, int line) {
|
||||
abortf_(exp, file, line);
|
||||
}
|
||||
@@ -5278,8 +5220,21 @@ HTSEXT_API int hts_log(httrackp * opt, const char *prefix, const char *msg) {
|
||||
return 1; /* Error */
|
||||
}
|
||||
|
||||
static void (*hts_log_print_callback)(httrackp * opt, int type, const char *format, va_list args) = NULL;
|
||||
|
||||
HTSEXT_API void hts_set_log_vprint_callback(void (*callback)(httrackp * opt,
|
||||
int type, const char *format, va_list args)) {
|
||||
hts_log_print_callback = callback;
|
||||
}
|
||||
|
||||
HTSEXT_API void hts_log_vprint(httrackp * opt, int type, const char *format, va_list args) {
|
||||
assertf(format != NULL);
|
||||
if (hts_log_print_callback != NULL) {
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
hts_log_print_callback(opt, type, format, args);
|
||||
va_end(args_copy);
|
||||
}
|
||||
if (opt != NULL && opt->log != NULL) {
|
||||
const int save_errno = errno;
|
||||
const char *s_type = "unknown";
|
||||
@@ -5325,13 +5280,11 @@ HTSEXT_API void hts_log_vprint(httrackp * opt, int type, const char *format, va_
|
||||
}
|
||||
|
||||
HTSEXT_API void hts_log_print(httrackp * opt, int type, const char *format, ...) {
|
||||
va_list args;
|
||||
assertf(format != NULL);
|
||||
if (opt != NULL && opt->log != NULL) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
hts_log_vprint(opt, type, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
va_start(args, format);
|
||||
hts_log_vprint(opt, type, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
HTSEXT_API void set_wrappers(httrackp * opt) { // LEGACY
|
||||
@@ -5835,68 +5788,56 @@ const t_hts_htmlcheck_callbacks default_callbacks = {
|
||||
{htsdefault_parse, NULL}
|
||||
};
|
||||
|
||||
#define CHARCAST(A) ( (char*) (A) )
|
||||
#define OFFSET_OF(TYPE, MEMBER) ( (size_t) ( CHARCAST(&(((TYPE*) NULL)->MEMBER)) - CHARCAST((TYPE*) NULL) ) )
|
||||
#define CALLBACK_REF(name, fun) \
|
||||
{ name, OFFSET_OF(t_hts_htmlcheck_callbacks, fun) }
|
||||
#define MEMBER_OF(STRUCT, OFFSET, TYPE) ( * ((TYPE*)((char*)(STRUCT) + (OFFSET))) )
|
||||
#define CALLBACK_OP(CB, NAME, OPERATION, S, FUN) do { \
|
||||
if (strcmp(NAME, S) == 0) { \
|
||||
OPERATION(t_hts_htmlcheck_ ##FUN, (CB)->FUN.fun); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
const t_hts_callback_ref default_callbacks_ref[] = {
|
||||
CALLBACK_REF("init", init),
|
||||
CALLBACK_REF("free", uninit),
|
||||
CALLBACK_REF("start", start),
|
||||
CALLBACK_REF("end", end),
|
||||
CALLBACK_REF("change-options", chopt),
|
||||
CALLBACK_REF("preprocess-html", preprocess),
|
||||
CALLBACK_REF("postprocess-html", postprocess),
|
||||
CALLBACK_REF("check-html", check_html),
|
||||
CALLBACK_REF("query", query),
|
||||
CALLBACK_REF("query2", query2),
|
||||
CALLBACK_REF("query3", query3),
|
||||
CALLBACK_REF("loop", loop),
|
||||
CALLBACK_REF("check-link", check_link),
|
||||
CALLBACK_REF("check-mime", check_mime),
|
||||
CALLBACK_REF("pause", pause),
|
||||
CALLBACK_REF("save-file", filesave),
|
||||
CALLBACK_REF("save-file2", filesave2),
|
||||
CALLBACK_REF("link-detected", linkdetected),
|
||||
CALLBACK_REF("link-detected2", linkdetected2),
|
||||
CALLBACK_REF("transfer-status", xfrstatus),
|
||||
CALLBACK_REF("save-name", savename),
|
||||
CALLBACK_REF("send-header", sendhead),
|
||||
CALLBACK_REF("receive-header", receivehead),
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
size_t hts_get_callback_offs(const char *name) {
|
||||
const t_hts_callback_ref *ref;
|
||||
|
||||
for(ref = &default_callbacks_ref[0]; ref->name != NULL; ref++) {
|
||||
if (strcmp(name, ref->name) == 0) {
|
||||
return ref->offset;
|
||||
}
|
||||
}
|
||||
return (size_t) (-1);
|
||||
}
|
||||
#define DISPATCH_CALLBACK(CB, NAME, OPERATION) do { \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "init", init); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "free", uninit); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "start", start); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "end", end); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "change-options", chopt); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "preprocess-html", preprocess); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "postprocess-html", postprocess); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "check-html", check_html); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "query", query); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "query2", query2); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "query3", query3); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "loop", loop); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "check-link", check_link); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "check-mime", check_mime); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "pause", pause); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "save-file", filesave); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "save-file2", filesave2); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "link-detected", linkdetected); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "link-detected2", linkdetected2); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "transfer-status", xfrstatus); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "save-name", savename); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "send-header", sendhead); \
|
||||
CALLBACK_OP(CB, NAME, OPERATION, "receive-header", receivehead); \
|
||||
} while(0)
|
||||
|
||||
int hts_set_callback(t_hts_htmlcheck_callbacks * callbacks, const char *name,
|
||||
void *function) {
|
||||
size_t offs = hts_get_callback_offs(name);
|
||||
|
||||
if (offs != (size_t) - 1) {
|
||||
MEMBER_OF(callbacks, offs, void *) = function;
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
int error = 1;
|
||||
#define CALLBACK_OPERATION(TYPE, FUNCTION) do { \
|
||||
FUNCTION = (TYPE) function; \
|
||||
error = 0; \
|
||||
} while(0)
|
||||
DISPATCH_CALLBACK(callbacks, name, CALLBACK_OPERATION);
|
||||
#undef CALLBACK_OPERATION
|
||||
return error;
|
||||
}
|
||||
|
||||
void *hts_get_callback(t_hts_htmlcheck_callbacks * callbacks, const char *name) {
|
||||
size_t offs = hts_get_callback_offs(name);
|
||||
|
||||
if (offs != (size_t) - 1) {
|
||||
return MEMBER_OF(callbacks, offs, void *);
|
||||
}
|
||||
#define CALLBACK_OPERATION(TYPE, FUNCTION) do { \
|
||||
return (void*) FUNCTION; \
|
||||
} while(0)
|
||||
DISPATCH_CALLBACK(callbacks, name, CALLBACK_OPERATION);
|
||||
#undef CALLBACK_OPERATION
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
21
src/htslib.h
21
src/htslib.h
@@ -158,7 +158,7 @@ struct htsblk {
|
||||
short int is_file; // ce n'est pas une socket mais un descripteur de fichier si 1
|
||||
T_SOC soc; // ID socket
|
||||
SOCaddr address; // IP address
|
||||
int address_size; // IP address structure length
|
||||
int address_size; // IP address structure length (unused internally)
|
||||
FILE *fp; // fichier pour file://
|
||||
#if HTS_USEOPENSSL
|
||||
short int ssl; // is this connection a SSL one? (https)
|
||||
@@ -273,12 +273,16 @@ void treatfirstline(htsblk * retour, char *rcvd);
|
||||
|
||||
// sous-fonctions
|
||||
LLint http_xfread1(htsblk * r, int bufl);
|
||||
HTS_INLINE t_hostent *hts_gethostbyname2(httrackp * opt, const char *iadr,
|
||||
void *v_buffer, const char **error);
|
||||
HTS_INLINE t_hostent *hts_gethostbyname(httrackp * opt, const char *iadr,
|
||||
void *v_buffer);
|
||||
HTSEXT_API t_hostent *vxgethostbyname2(const char *const hostname, void *v_buffer, const char **error);
|
||||
HTSEXT_API t_hostent *vxgethostbyname(const char *const hostname, void *v_buffer);
|
||||
HTS_INLINE SOCaddr* hts_dns_resolve2(httrackp * opt, const char *iadr,
|
||||
SOCaddr *const addr,
|
||||
const char **error);
|
||||
HTS_INLINE SOCaddr* hts_dns_resolve(httrackp * opt, const char *iadr,
|
||||
SOCaddr *const addr);
|
||||
HTSEXT_API SOCaddr* hts_dns_resolve_nocache2(const char *const hostname,
|
||||
SOCaddr *const addr,
|
||||
const char **error);
|
||||
HTSEXT_API SOCaddr* hts_dns_resolve_nocache(const char *const hostname,
|
||||
SOCaddr *const addr);
|
||||
HTSEXT_API int check_hostname_dns(const char *const hostname);
|
||||
|
||||
int ftp_available(void);
|
||||
@@ -303,7 +307,7 @@ HTS_INLINE void time_rfc822(char *s, struct tm *A);
|
||||
HTS_INLINE void time_rfc822_local(char *s, struct tm *A);
|
||||
|
||||
HTS_INLINE int sendc(htsblk * r, const char *s);
|
||||
int finput(int fd, char *s, int max);
|
||||
int finput(T_SOC fd, char *s, int max);
|
||||
int binput(char *buff, char *s, int max);
|
||||
int linput(FILE * fp, char *s, int max);
|
||||
int linputsoc(T_SOC soc, char *s, int max);
|
||||
@@ -384,7 +388,6 @@ extern void *getFunctionPtr(void *handle, const char *fncname);
|
||||
extern void closeFunctionLib(void *handle);
|
||||
|
||||
extern void clearCallbacks(htscallbacks * chain);
|
||||
extern size_t hts_get_callback_offs(const char *name);
|
||||
int hts_set_callback(t_hts_htmlcheck_callbacks * callbacks,
|
||||
const char *name, void *function);
|
||||
void *hts_get_callback(t_hts_htmlcheck_callbacks * callbacks,
|
||||
|
||||
@@ -812,7 +812,7 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
|
||||
name[pos][0] = '\0';
|
||||
}
|
||||
pos = 0;
|
||||
while(*a != ']') {
|
||||
while(*a != '\0' && *a != ']') {
|
||||
if (pos < 5) {
|
||||
if (*a == ':') { // next token
|
||||
c = name[++pos];
|
||||
@@ -823,7 +823,9 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
|
||||
}
|
||||
}
|
||||
}
|
||||
a++;
|
||||
if (*a == ']') {
|
||||
a++;
|
||||
}
|
||||
strcatbuff(name[0], "="); /* param=.. */
|
||||
c = strchr(fil_complete, '?');
|
||||
/* parameters exists */
|
||||
@@ -1695,9 +1697,9 @@ void url_savename_refname(const char *adr, const char *fil, char *filename) {
|
||||
MD5_CTX ctx;
|
||||
|
||||
MD5Init(&ctx, 0);
|
||||
MD5Update(&ctx, (const unsigned char *) adr, strlen(adr));
|
||||
MD5Update(&ctx, (const unsigned char *) adr, (int) strlen(adr));
|
||||
MD5Update(&ctx, (const unsigned char *) ",", 1);
|
||||
MD5Update(&ctx, (const unsigned char *) fil, strlen(fil));
|
||||
MD5Update(&ctx, (const unsigned char *) fil, (int) strlen(fil));
|
||||
MD5Final(bindigest, &ctx);
|
||||
sprintf(filename,
|
||||
CACHE_REFNAME "/" "%02x%02x%02x%02x%02x%02x%02x%02x"
|
||||
|
||||
312
src/htsnet.h
312
src/htsnet.h
@@ -38,6 +38,7 @@ Please visit our Website: http://www.httrack.com
|
||||
/* basic net definitions */
|
||||
#include "htsglobal.h"
|
||||
#include "htsbasenet.h"
|
||||
#include "htssafe.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef _WIN32
|
||||
@@ -45,6 +46,8 @@ Please visit our Website: http://www.httrack.com
|
||||
#include <io.h>
|
||||
// pour FindFirstFile
|
||||
#include <winbase.h>
|
||||
typedef USHORT in_port_t;
|
||||
typedef ADDRESS_FAMILY sa_family_t;
|
||||
#else
|
||||
//typedef int T_SOC;
|
||||
#define INVALID_SOCKET -1
|
||||
@@ -70,87 +73,12 @@ typedef unsigned long in_addr_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** ipV4 **
|
||||
*/
|
||||
#if HTS_INET6==0
|
||||
|
||||
/* Ipv4 structures */
|
||||
typedef struct in_addr INaddr;
|
||||
|
||||
/* This should handle all cases */
|
||||
#ifndef HTS_DEF_FWSTRUCT_SOCaddr
|
||||
#define HTS_DEF_FWSTRUCT_SOCaddr
|
||||
typedef struct SOCaddr SOCaddr;
|
||||
#endif
|
||||
struct SOCaddr {
|
||||
union {
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr sa;
|
||||
unsigned char v4data[4];
|
||||
unsigned char v6data[16];
|
||||
unsigned char pad[128];
|
||||
} m_addr;
|
||||
};
|
||||
|
||||
/* Ipv4 structure members */
|
||||
#define SOCaddr_sinaddr(server) ((server).m_addr.in.sin_addr)
|
||||
#define SOCaddr_sinfamily(server) ((server).m_addr.in.sin_family)
|
||||
#define SOCaddr_sinport(server) ((server).m_addr.in.sin_port)
|
||||
|
||||
/* AF_xx */
|
||||
#define AFinet AF_INET
|
||||
|
||||
/* Set port to sockaddr structure */
|
||||
#define SOCaddr_initport(server, port) do { \
|
||||
SOCaddr_sinport(server) = htons((unsigned short int) (port)); \
|
||||
} while(0)
|
||||
|
||||
#define SOCaddr_initany(server, server_len) do { \
|
||||
SOCaddr_sinfamily(server) = AF_INET; \
|
||||
memset(&SOCaddr_sinaddr(server), 0, sizeof(struct sockaddr_in)); \
|
||||
server_len=sizeof(struct sockaddr_in); \
|
||||
} while(0)
|
||||
|
||||
/* Copy sockaddr to another one */
|
||||
#define SOCaddr_copyaddr(server, server_len, hpaddr, hpsize) do { \
|
||||
if (hpsize == sizeof(struct sockaddr_in)) { \
|
||||
server_len=sizeof(struct sockaddr_in); \
|
||||
SOCaddr_sinfamily(server) = (*(struct sockaddr_in*)(hpaddr)).sin_family; \
|
||||
SOCaddr_sinport(server) = (*(struct sockaddr_in*)(hpaddr)).sin_port; \
|
||||
memcpy(&SOCaddr_sinaddr(server), &(*(struct sockaddr_in*)(hpaddr)).sin_addr, sizeof(SOCaddr_sinaddr(server))); \
|
||||
} else if (hpsize == 4) {\
|
||||
server_len=sizeof(struct sockaddr_in); \
|
||||
SOCaddr_sinfamily(server) = AF_INET; \
|
||||
SOCaddr_sinport(server) = 0; \
|
||||
memcpy(&SOCaddr_sinaddr(server), (hpaddr), sizeof(SOCaddr_sinaddr(server))); \
|
||||
} else if ((hpsize > 0) && (hpsize <= sizeof(server))) { \
|
||||
server_len=hpsize; \
|
||||
memcpy(&(server), hpaddr, hpsize); \
|
||||
} else { \
|
||||
server_len=0; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Get dotted address */
|
||||
#define SOCaddr_inetntoa(namebuf, namebuflen, ss, sslen) do { \
|
||||
char* dot = (char*) inet_ntoa(SOCaddr_sinaddr(ss)); \
|
||||
(namebuf)[0]='\0'; \
|
||||
if (dot) { \
|
||||
strcpy(namebuf, dot); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Get protocol ID */
|
||||
#define SOCaddr_getproto(ss, sslen) ('1')
|
||||
|
||||
/*
|
||||
** ipV6 **
|
||||
*/
|
||||
#else
|
||||
|
||||
/* Ipv4 structures */
|
||||
#if HTS_INET6 != 0
|
||||
typedef struct in6_addr INaddr;
|
||||
#else
|
||||
typedef struct in_addr INaddr;
|
||||
#endif
|
||||
|
||||
/* This should handle all cases */
|
||||
#ifndef HTS_DEF_FWSTRUCT_SOCaddr
|
||||
@@ -159,117 +87,169 @@ typedef struct SOCaddr SOCaddr;
|
||||
#endif
|
||||
struct SOCaddr {
|
||||
union {
|
||||
struct sockaddr_in6 in6;
|
||||
struct sockaddr_in in;
|
||||
/* Generic version, for network functions such as getnameinfo() */
|
||||
struct sockaddr sa;
|
||||
unsigned char v4data[4];
|
||||
unsigned char v6data[16];
|
||||
unsigned char pad[128];
|
||||
/* IPv4 */
|
||||
struct sockaddr_in in;
|
||||
#if HTS_INET6 != 0
|
||||
/* IPv6 */
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
} m_addr;
|
||||
};
|
||||
|
||||
/* Ipv4 structure members */
|
||||
#define SOCaddr_sinaddr(server) ((server).m_addr.in6.sin6_addr)
|
||||
#define SOCaddr_sinfamily(server) ((server).m_addr.in6.sin6_family)
|
||||
#define SOCaddr_sinport(server) ((server).m_addr.in6.sin6_port)
|
||||
#define SOCaddr_sinflowinfo(server) ((server).m_addr.in6.sin6_flowinfo)
|
||||
/* #define SOCaddr_sinscopeid(a) ((a).m_addr.in6.sin6_scope_id) */
|
||||
static HTS_INLINE HTS_UNUSED in_port_t* SOCaddr_sinport_(SOCaddr *const addr,
|
||||
const char *file, const int line) {
|
||||
assertf_(addr != NULL, file, line);
|
||||
switch(addr->m_addr.sa.sa_family) {
|
||||
case AF_INET:
|
||||
return &addr->m_addr.in.sin_port;
|
||||
break;
|
||||
#if HTS_INET6 != 0
|
||||
case AF_INET6:
|
||||
return &addr->m_addr.in6.sin6_port;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assertf_(! "invalid structure", file, line);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static HTS_INLINE HTS_UNUSED socklen_t SOCaddr_size_(const SOCaddr*const addr,
|
||||
const char *file, const int line) {
|
||||
assertf_(addr != NULL, file, line);
|
||||
switch(addr->m_addr.sa.sa_family) {
|
||||
case AF_INET:
|
||||
return sizeof(addr->m_addr.in);
|
||||
break;
|
||||
#if HTS_INET6 != 0
|
||||
case AF_INET6:
|
||||
return sizeof(addr->m_addr.in6);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static HTS_INLINE HTS_UNUSED void SOCaddr_clear_(SOCaddr*const addr,
|
||||
const char *file, const int line) {
|
||||
assertf_(addr != NULL, file, line);
|
||||
addr->m_addr.sa.sa_family = AF_UNSPEC;
|
||||
}
|
||||
|
||||
/* Ipv4/6 structure members */
|
||||
#define SOCaddr_sinfamily(server) ((server).m_addr.sa.sa_family)
|
||||
#define SOCaddr_sinport(server) (*SOCaddr_sinport_(&(server), __FILE__, __LINE__))
|
||||
#define SOCaddr_size(server) (SOCaddr_size_(&(server), __FILE__, __LINE__))
|
||||
#define SOCaddr_is_valid(server) (SOCaddr_size_(&(server), __FILE__, __LINE__) != 0 )
|
||||
#define SOCaddr_clear(server) SOCaddr_clear_(&(server), __FILE__, __LINE__)
|
||||
#define SOCaddr_sockaddr(server) ((server).m_addr.sa)
|
||||
#define SOCaddr_capacity(server) sizeof((server).m_addr)
|
||||
|
||||
/* AF_xx */
|
||||
#if HTS_INET6 != 0
|
||||
#define AFinet AF_INET6
|
||||
#else
|
||||
#define AFinet AF_INET
|
||||
#endif
|
||||
|
||||
/* Set port to sockaddr structure */
|
||||
#define SOCaddr_initport(server, port) do { \
|
||||
SOCaddr_sinport(server) = htons((unsigned short int) (port)); \
|
||||
SOCaddr_sinport(server) = htons((in_port_t) (port)); \
|
||||
} while(0)
|
||||
|
||||
#define SOCaddr_initany(server, server_len) do { \
|
||||
SOCaddr_sinfamily(server) = AF_INET; \
|
||||
memset(&SOCaddr_sinaddr(server), 0, sizeof(struct sockaddr_in)); \
|
||||
server_len=sizeof(struct sockaddr_in); \
|
||||
static HTS_INLINE HTS_UNUSED socklen_t SOCaddr_initany_(SOCaddr*const addr,
|
||||
const char *file, const int line) {
|
||||
assertf_(addr != NULL, file, line);
|
||||
memset(&addr->m_addr.in, 0, sizeof(addr->m_addr.in));
|
||||
addr->m_addr.in.sin_family = AF_INET;
|
||||
return SOCaddr_size_(addr, file, line);
|
||||
}
|
||||
|
||||
#define SOCaddr_initany(server) do { \
|
||||
SOCaddr_initany_(&(server), __FILE__, __LINE__); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
Copy sockaddr to SOCaddr
|
||||
|
||||
Note;
|
||||
The '> sizeof(struct sockaddr_in6)' hack if for the VC6 structure which
|
||||
lacks the scope id
|
||||
Copy sockaddr_in/sockaddr_in6/raw IPv4/raw IPv6 to our opaque SOCaddr
|
||||
*/
|
||||
static HTS_UNUSED socklen_t SOCaddr_copyaddr_(SOCaddr*const server,
|
||||
const void *data, const size_t data_size,
|
||||
const char *file, const int line) {
|
||||
assertf_(server != NULL, file, line);
|
||||
assertf_(data != NULL, file, line);
|
||||
|
||||
if (data_size == sizeof(struct sockaddr_in)) {
|
||||
memcpy(&server->m_addr.in, data, sizeof(struct sockaddr_in));
|
||||
assertf_(server->m_addr.sa.sa_family == AF_INET, file, line);
|
||||
#if HTS_INET6 != 0
|
||||
} else if (data_size == sizeof(struct sockaddr_in6)) {
|
||||
memcpy(&server->m_addr.in6, data, sizeof(struct sockaddr_in6));
|
||||
assertf_(server->m_addr.sa.sa_family == AF_INET6, file, line);
|
||||
#endif
|
||||
} else if (data_size == 4) {
|
||||
memset(&server->m_addr.in, 0, sizeof(server->m_addr.in));
|
||||
server->m_addr.in.sin_family = AF_INET;
|
||||
server->m_addr.in.sin_port = 0;
|
||||
memcpy(&server->m_addr.in.sin_addr, data, 4);
|
||||
#if HTS_INET6 != 0
|
||||
} else if (data_size == 16) {
|
||||
memset(&server->m_addr.in6, 0, sizeof(server->m_addr.in6));
|
||||
server->m_addr.in6.sin6_family = AF_INET6;
|
||||
server->m_addr.in6.sin6_port = 0;
|
||||
memcpy(&server->m_addr.in6.sin6_addr, data, 16);
|
||||
#endif
|
||||
} else {
|
||||
server->m_addr.in.sin_family = AF_INET;
|
||||
}
|
||||
return SOCaddr_size_(server, file, line);
|
||||
}
|
||||
|
||||
#define SOCaddr_copyaddr(server, server_len, hpaddr, hpsize) do { \
|
||||
if (hpsize == sizeof(struct sockaddr_in6)) { \
|
||||
server_len=sizeof(struct sockaddr_in6); \
|
||||
SOCaddr_sinfamily(server) = (*(struct sockaddr_in6*)(hpaddr)).sin6_family; \
|
||||
SOCaddr_sinport(server) = (*(struct sockaddr_in6*)(hpaddr)).sin6_port; \
|
||||
SOCaddr_sinflowinfo(server) = (*(struct sockaddr_in6*)(hpaddr)).sin6_flowinfo; \
|
||||
memcpy(&SOCaddr_sinaddr(server), &(*(struct sockaddr_in6*)(hpaddr)).sin6_addr, sizeof(SOCaddr_sinaddr(server))); \
|
||||
} else if (hpsize > sizeof(struct sockaddr_in6)) { \
|
||||
server_len=hpsize; \
|
||||
SOCaddr_sinport(server) = 0; \
|
||||
memcpy(&(server), hpaddr, hpsize); \
|
||||
} else if (hpsize == sizeof(struct sockaddr_in)) { \
|
||||
server_len=sizeof(struct sockaddr_in); \
|
||||
(*(struct sockaddr_in*)(&server)).sin_family = AF_INET; \
|
||||
SOCaddr_sinport(server) = (*(struct sockaddr_in*)(hpaddr)).sin_port; \
|
||||
memcpy(&(*(struct sockaddr_in*)&(server)).sin_addr, &(*(struct sockaddr_in*)(hpaddr)).sin_addr, sizeof((*(struct sockaddr_in*)(hpaddr)).sin_addr)); \
|
||||
} else if (hpsize == 4) {\
|
||||
server_len=sizeof(struct sockaddr_in); \
|
||||
(*(struct sockaddr_in*)(&server)).sin_family = AF_INET; \
|
||||
SOCaddr_sinport(server) = 0; \
|
||||
memcpy(&(*(struct sockaddr_in*)&(server)).sin_addr, hpaddr, 4); \
|
||||
} else if (hpsize == 16) {\
|
||||
server_len=sizeof(struct sockaddr_in6); \
|
||||
SOCaddr_sinfamily(server) = AF_INET6; \
|
||||
SOCaddr_sinport(server) = 0; \
|
||||
memcpy(&SOCaddr_sinaddr(server), (hpaddr), 16); \
|
||||
} else if ((hpsize > 0) && (hpsize <= sizeof(server))) { \
|
||||
server_len=hpsize; \
|
||||
memcpy(&(server), hpaddr, hpsize); \
|
||||
} else { \
|
||||
server_len=0; \
|
||||
} \
|
||||
server_len = (int) SOCaddr_copyaddr_(&(server), hpaddr, hpsize, __FILE__, __LINE__); \
|
||||
} while(0)
|
||||
|
||||
#define SOCaddr_copyaddr2(server, hpaddr, hpsize) do { \
|
||||
(void) SOCaddr_copyaddr_(&(server), hpaddr, hpsize, __FILE__, __LINE__); \
|
||||
} while(0)
|
||||
|
||||
#define SOCaddr_copy_SOCaddr(dest, src) do { \
|
||||
SOCaddr_copyaddr_(&(dest), &(src).m_addr.sa, SOCaddr_size(src), __FILE__, __LINE__); \
|
||||
} while(0)
|
||||
|
||||
/* Get dotted address */
|
||||
#define SOCaddr_inetntoa(namebuf, namebuflen, ss, sslen) do { \
|
||||
char *pos_; \
|
||||
(namebuf)[0]='\0'; \
|
||||
getnameinfo((struct sockaddr *)&(ss), sslen, \
|
||||
(namebuf), namebuflen, NULL, 0, NI_NUMERICHOST); \
|
||||
/* remove scope id */ \
|
||||
pos_ = strrchr(namebuf, '%'); \
|
||||
if (pos_ != NULL) { \
|
||||
*pos_ = '\0'; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static HTS_UNUSED void SOCaddr_inetntoa_(char *namebuf, size_t namebuflen,
|
||||
SOCaddr *const ss,
|
||||
const char *file, const int line) {
|
||||
assertf_(namebuf != NULL, file, line);
|
||||
assertf_(ss != NULL, file, line);
|
||||
|
||||
if (getnameinfo(&ss->m_addr.sa, sizeof(ss->m_addr),
|
||||
namebuf, namebuflen,
|
||||
NULL, 0,
|
||||
NI_NUMERICHOST) == 0) {
|
||||
/* remove scope id(s) */
|
||||
char *const pos = strchr(namebuf, '%');
|
||||
if (pos != NULL) {
|
||||
*pos = '\0';
|
||||
}
|
||||
} else {
|
||||
namebuf[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#define SOCaddr_inetntoa(namebuf, namebuflen, ss) \
|
||||
SOCaddr_inetntoa_(namebuf, namebuflen, &(ss), __FILE__, __LINE__)
|
||||
|
||||
/* Get protocol ID */
|
||||
#define SOCaddr_getproto(ss, sslen) ((sslen == sizeof(struct sockaddr_in6))?('2'):('1'))
|
||||
|
||||
#endif
|
||||
#define SOCaddr_getproto(ss) ( SOCaddr_size(ss) == sizeof(struct sockaddr_in) ? '1' : '2')
|
||||
|
||||
/* Socket length type */
|
||||
typedef socklen_t SOClen;
|
||||
|
||||
/* Buffer structure to copy various hostent structures */
|
||||
#ifndef HTS_DEF_FWSTRUCT_t_fullhostent
|
||||
#define HTS_DEF_FWSTRUCT_t_fullhostent
|
||||
typedef struct t_fullhostent t_fullhostent;
|
||||
#endif
|
||||
struct t_fullhostent {
|
||||
t_hostent hp;
|
||||
char *list[2];
|
||||
char addr[HTS_MAXADDRLEN]; /* various struct sockaddr structures */
|
||||
unsigned int addr_maxlen;
|
||||
};
|
||||
|
||||
/* Initialize a t_fullhostent structure */
|
||||
#define fullhostent_init(h) do { \
|
||||
memset((h), 0, sizeof(t_fullhostent)); \
|
||||
(h)->hp.h_addr_list = (char **) & ((h)->list); \
|
||||
(h)->list[0] = (char *) & ((h)->addr); \
|
||||
(h)->list[1] = NULL; \
|
||||
(h)->addr_maxlen = HTS_MAXADDRLEN; \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3606,7 +3606,7 @@ int hts_mirror_check_moved(htsmoduleStruct * str,
|
||||
urladr, urlfil, mov_adr, mov_fil);
|
||||
// canceller lien actuel
|
||||
error = 1;
|
||||
strcpybuff(liens[ptr]->adr, "!"); // caractère bidon (invalide hash)
|
||||
hash_invalidate_entry(hashptr, ptr); // invalidate hashtable entry
|
||||
// noter NOUVEAU lien
|
||||
//xxc xxc
|
||||
// set_prio_to=0+1; // protection if the moved URL is an html page!!
|
||||
@@ -3742,7 +3742,7 @@ int hts_mirror_check_moved(htsmoduleStruct * str,
|
||||
//
|
||||
// canceller lien actuel
|
||||
error = 1;
|
||||
strcpybuff(liens[ptr]->adr, "!"); // caractère bidon (invalide hash)
|
||||
hash_invalidate_entry(hashptr, ptr); // invalidate hashtable entry
|
||||
//
|
||||
} else { // oups erreur, plus de mémoire!!
|
||||
printf("PANIC! : Not enough memory [%d]\n", __LINE__);
|
||||
|
||||
@@ -35,17 +35,26 @@ Please visit our Website: http://www.httrack.com
|
||||
|
||||
#include "htsglobal.h"
|
||||
|
||||
/**
|
||||
* Optional user-defined callback upon fatal error.
|
||||
*/
|
||||
typedef void (*htsErrorCallback) (const char *msg, const char *file, int line);
|
||||
|
||||
/**
|
||||
* Emergency logging.
|
||||
* Default is to use libhttrack one.
|
||||
*/
|
||||
#ifndef HTSSAFE_ABORT_FUNCTION
|
||||
HTSEXT_API htsErrorCallback htsCallbackErr;
|
||||
#define HTSSAFE_ABORT_FUNCTION(A,B,C) do { if (htsCallbackErr != NULL) { htsCallbackErr(A,B,C); } } while(0)
|
||||
|
||||
/** Assert error callback. **/
|
||||
#ifndef HTS_DEF_FWSTRUCT_htsErrorCallback
|
||||
#define HTS_DEF_FWSTRUCT_htsErrorCallback
|
||||
typedef void (*htsErrorCallback) (const char *msg, const char *file, int line);
|
||||
HTSEXT_API htsErrorCallback hts_get_error_callback(void);
|
||||
#endif
|
||||
|
||||
#define HTSSAFE_ABORT_FUNCTION(A,B,C) do { \
|
||||
htsErrorCallback callback = hts_get_error_callback(); \
|
||||
if (callback != NULL) { \
|
||||
callback(A,B,C); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -61,7 +70,7 @@ HTSEXT_API htsErrorCallback htsCallbackErr;
|
||||
/**
|
||||
* Fatal assertion check.
|
||||
*/
|
||||
#define assertf_(exp, file, line) assertf__(exp, #exp, __FILE__, __LINE__)
|
||||
#define assertf_(exp, file, line) assertf__(exp, #exp, file, line)
|
||||
|
||||
/**
|
||||
* Fatal assertion check.
|
||||
@@ -91,6 +100,17 @@ static HTS_UNUSED void abortf_(const char *exp, const char *file, int line) {
|
||||
#endif
|
||||
#define HTS_IS_NOT_CHAR_BUFFER(VAR) ( ! HTS_IS_CHAR_BUFFER(VAR) )
|
||||
|
||||
/* Compile-time checks. */
|
||||
static HTS_UNUSED void htssafe_compile_time_check_(void) {
|
||||
char array[32];
|
||||
char *pointer = array;
|
||||
char check_array[HTS_IS_CHAR_BUFFER(array) ? 1 : -1];
|
||||
char check_pointer[HTS_IS_CHAR_BUFFER(pointer) ? -1 : 1];
|
||||
(void) pointer;
|
||||
(void) check_array;
|
||||
(void) check_pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append at most N characters from "B" to "A".
|
||||
* If "A" is a char[] variable whose size is not sizeof(char*), then the size
|
||||
@@ -130,13 +150,22 @@ static HTS_UNUSED void abortf_(const char *exp, const char *file, int line) {
|
||||
#define strlcatbuff(A, B, S) \
|
||||
strncat_safe_(A, S, B, \
|
||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), (size_t) -1, \
|
||||
"overflow while appending '" #B "' to '"#A"'", __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Copy characters of "B" to "A", "A" having a maximum capacity of "S".
|
||||
*/
|
||||
#define strlcpybuff(A, B, S) \
|
||||
strcpy_safe_(A, S, B, \
|
||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
||||
"overflow while copying '" #B "' to '"#A"'", __FILE__, __LINE__)
|
||||
|
||||
static HTS_INLINE HTS_UNUSED size_t strlen_safe_(const char *source, const size_t sizeof_source,
|
||||
const char *file, int line) {
|
||||
size_t size;
|
||||
assertf_( source != NULL, file, line );
|
||||
size = strnlen(source, sizeof_source);
|
||||
size = sizeof_source != (size_t) -1
|
||||
? strnlen(source, sizeof_source) : strlen(source);
|
||||
assertf_( size < sizeof_source, file, line );
|
||||
return size;
|
||||
}
|
||||
|
||||
171
src/htsserver.c
171
src/htsserver.c
@@ -119,16 +119,16 @@ HTS_UNUSED static int linputsoc_t(T_SOC soc, char *s, int max, int timeout);
|
||||
HTS_UNUSED static int linput(FILE * fp, char *s, int max);
|
||||
|
||||
/* Language files */
|
||||
HTS_UNUSED static int htslang_load(char *limit_to, char *apppath);
|
||||
HTS_UNUSED static void conv_printf(char *from, char *to);
|
||||
HTS_UNUSED static int htslang_load(char *limit_to, const char *apppath);
|
||||
HTS_UNUSED static void conv_printf(const char *from, char *to);
|
||||
HTS_UNUSED static void LANG_DELETE(void);
|
||||
HTS_UNUSED static void LANG_INIT(char *path);
|
||||
HTS_UNUSED static int LANG_T(char *path, int l);
|
||||
HTS_UNUSED static void LANG_INIT(const char *path);
|
||||
HTS_UNUSED static int LANG_T(const char *path, int l);
|
||||
HTS_UNUSED static int QLANG_T(int l);
|
||||
HTS_UNUSED static char *LANGSEL(char *name);
|
||||
HTS_UNUSED static char *LANGINTKEY(char *name);
|
||||
HTS_UNUSED static int LANG_SEARCH(char *path, char *iso);
|
||||
HTS_UNUSED static int LANG_LIST(char *path, char *buffer);
|
||||
HTS_UNUSED static const char *LANGSEL(const char *name);
|
||||
HTS_UNUSED static const char *LANGINTKEY(const char *name);
|
||||
HTS_UNUSED static int LANG_SEARCH(const char *path, const char *iso);
|
||||
HTS_UNUSED static int LANG_LIST(const char *path, char *buffer, size_t size);
|
||||
|
||||
// URL Link catcher
|
||||
|
||||
@@ -162,16 +162,15 @@ T_SOC smallserver_init_std(int *port_prox, char *adr_prox, int defaultPort) {
|
||||
// 1- Init the URL catcher
|
||||
|
||||
// get hostname. return 1 upon success.
|
||||
static int gethost(const char *hostname, SOCaddr * server, size_t server_size) {
|
||||
static int gethost(const char *hostname, SOCaddr * server) {
|
||||
if (hostname != NULL && *hostname != '\0') {
|
||||
#if HTS_INET6==0
|
||||
/* ipV4 resolver */
|
||||
t_hostent *hp = gethostbyname(hostname);
|
||||
struct hostent *hp = gethostbyname(hostname);
|
||||
|
||||
if (hp != NULL) {
|
||||
if (hp->h_length) {
|
||||
SOCaddr_copyaddr(*server, server_size, hp->h_addr_list[0],
|
||||
hp->h_length);
|
||||
SOCaddr_copyaddr2(*server, hp->h_addr_list[0], hp->h_length);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -187,7 +186,7 @@ static int gethost(const char *hostname, SOCaddr * server, size_t server_size) {
|
||||
if (getaddrinfo(hostname, NULL, &hints, &res) == 0) {
|
||||
if (res) {
|
||||
if ((res->ai_addr) && (res->ai_addrlen)) {
|
||||
SOCaddr_copyaddr(*server, server_size, res->ai_addr, res->ai_addrlen);
|
||||
SOCaddr_copyaddr2(*server, res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
return 1;
|
||||
}
|
||||
@@ -204,7 +203,7 @@ static int gethost(const char *hostname, SOCaddr * server, size_t server_size) {
|
||||
static int my_getlocalhost(char *h_loc, size_t size) {
|
||||
SOCaddr addr;
|
||||
strcpy(h_loc, "localhost");
|
||||
if (gethost(h_loc, &addr, sizeof(addr)) == 1) {
|
||||
if (gethost(h_loc, &addr) == 1) {
|
||||
return 0;
|
||||
}
|
||||
// come on ...
|
||||
@@ -220,7 +219,7 @@ static int my_gethostname(char *h_loc, size_t size) {
|
||||
h_loc[0] = '\0';
|
||||
if (gethostname(h_loc, (int) size) == 0) { // host name
|
||||
SOCaddr addr;
|
||||
if (gethost(h_loc, &addr, sizeof(addr)) == 1) {
|
||||
if (gethost(h_loc, &addr) == 1) {
|
||||
return 0;
|
||||
} else {
|
||||
return my_getlocalhost(h_loc, size);
|
||||
@@ -247,54 +246,16 @@ T_SOC smallserver_init(int *port, char *adr) {
|
||||
|
||||
if (my_gethostname(h_loc, 256) == 0) { // host name
|
||||
SOCaddr server;
|
||||
int server_size = sizeof(server);
|
||||
|
||||
/*t_hostent* hp_loc;
|
||||
t_fullhostent buffer; */
|
||||
|
||||
// effacer structure
|
||||
memset(&server, 0, sizeof(server));
|
||||
|
||||
/*if ( (hp_loc=vxgethostbyname(h_loc, &buffer)) ) */
|
||||
{
|
||||
// copie adresse
|
||||
// NO (bind all)
|
||||
// SOCaddr_copyaddr(server, server_size, hp_loc->h_addr_list[0], hp_loc->h_length);
|
||||
|
||||
SOCaddr_initany(server, server_size);
|
||||
if ((soc =
|
||||
(T_SOC) socket(SOCaddr_sinfamily(server), SOCK_STREAM,
|
||||
0)) != INVALID_SOCKET) {
|
||||
SOCaddr_initport(server, *port);
|
||||
if (bind(soc, (struct sockaddr *) &server, server_size) == 0) {
|
||||
/*SOClen len;
|
||||
SOCaddr server2;
|
||||
len=sizeof(server2); */
|
||||
// effacer structure
|
||||
/*memset(&server2, 0, sizeof(server2));
|
||||
if (getsockname(soc,(struct sockaddr*) &server2,&len) == 0) {
|
||||
*port=ntohs(SOCaddr_sinport(server)); // récupérer port */
|
||||
if (listen(soc, 10) >= 0) { // au pif le 10
|
||||
// SOCaddr_inetntoa(adr, 128, server2, len);
|
||||
strcpy(adr, h_loc);
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
closesocket(soc);
|
||||
#else
|
||||
close(soc);
|
||||
#endif
|
||||
soc = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
/*} else {
|
||||
#ifdef _WIN32
|
||||
closesocket(soc);
|
||||
#else
|
||||
close(soc);
|
||||
#endif
|
||||
soc=INVALID_SOCKET;
|
||||
} */
|
||||
|
||||
SOCaddr_initany(server);
|
||||
if ((soc =
|
||||
(T_SOC) socket(SOCaddr_sinfamily(server), SOCK_STREAM,
|
||||
0)) != INVALID_SOCKET) {
|
||||
SOCaddr_initport(server, *port);
|
||||
if (bind(soc, &SOCaddr_sockaddr(server), SOCaddr_size(server)) == 0) {
|
||||
if (listen(soc, 10) >= 0) {
|
||||
// SOCaddr_inetntoa(adr, 128, server2);
|
||||
strcpy(adr, h_loc);
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
closesocket(soc);
|
||||
@@ -303,6 +264,13 @@ T_SOC smallserver_init(int *port, char *adr) {
|
||||
#endif
|
||||
soc = INVALID_SOCKET;
|
||||
}
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
closesocket(soc);
|
||||
#else
|
||||
close(soc);
|
||||
#endif
|
||||
soc = INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -936,7 +904,7 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
|
||||
&& (n = (pos - str)) && n < 1024) {
|
||||
char name_[1024 + 2];
|
||||
char *name = name_;
|
||||
char *langstr = NULL;
|
||||
const char *langstr = NULL;
|
||||
int p;
|
||||
int format = 0;
|
||||
int listDefault = 0;
|
||||
@@ -1171,8 +1139,8 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
|
||||
if (langstr == NULL) {
|
||||
if (strfield2(name, "#iso")) {
|
||||
langstr = line2;
|
||||
langstr[0] = '\0';
|
||||
LANG_LIST(path, langstr);
|
||||
line2[0] = '\0';
|
||||
LANG_LIST(path, line2, sizeof(line2));
|
||||
assertf(strlen(langstr) < sizeof(line2) - 2);
|
||||
} else {
|
||||
langstr = LANGSEL(name);
|
||||
@@ -1191,7 +1159,7 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
|
||||
switch (format) {
|
||||
case 0:
|
||||
{
|
||||
char *a = langstr;
|
||||
const char *a = langstr;
|
||||
|
||||
while(*a) {
|
||||
if (a[0] == '\\' && isxdigit(a[1])
|
||||
@@ -1237,7 +1205,7 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
|
||||
default:
|
||||
if (*langstr) {
|
||||
int id = 1;
|
||||
char *fstr = langstr;
|
||||
const char *fstr = langstr;
|
||||
|
||||
StringClear(tmpbuff);
|
||||
if (format == 2) {
|
||||
@@ -1460,24 +1428,25 @@ int htslang_uninit(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smallserver_setkey(char *key, char *value) {
|
||||
int smallserver_setkey(const char *key, const char *value) {
|
||||
return inthash_write(NewLangList, key, (intptr_t) strdup(value));
|
||||
}
|
||||
int smallserver_setkeyint(char *key, LLint value) {
|
||||
|
||||
int smallserver_setkeyint(const char *key, LLint value) {
|
||||
char tmp[256];
|
||||
|
||||
sprintf(tmp, LLintP, value);
|
||||
snprintf(tmp, sizeof(tmp), LLintP, value);
|
||||
return inthash_write(NewLangList, key, (intptr_t) strdup(tmp));
|
||||
}
|
||||
int smallserver_setkeyarr(char *key, int id, char *key2, char *value) {
|
||||
int smallserver_setkeyarr(const char *key, int id, const char *key2, const char *value) {
|
||||
char tmp[256];
|
||||
|
||||
sprintf(tmp, "%s%d%s", key, id, key2);
|
||||
snprintf(tmp, sizeof(tmp), "%s%d%s", key, id, key2);
|
||||
return inthash_write(NewLangList, tmp, (intptr_t) strdup(value));
|
||||
}
|
||||
|
||||
static int htslang_load(char *limit_to, char *path) {
|
||||
char *hashname;
|
||||
static int htslang_load(char *limit_to, const char *path) {
|
||||
const char *hashname;
|
||||
char catbuff[CATBUFF_SIZE];
|
||||
|
||||
//
|
||||
@@ -1511,7 +1480,7 @@ static int htslang_load(char *limit_to, char *path) {
|
||||
linput_cpp(fp, intkey, 8000);
|
||||
linput_cpp(fp, key, 8000);
|
||||
if (strnotempty(intkey) && strnotempty(key)) {
|
||||
char *test = LANGINTKEY(key);
|
||||
const char *test = LANGINTKEY(key);
|
||||
|
||||
/* Increment for multiple definitions */
|
||||
if (strnotempty(test)) {
|
||||
@@ -1593,7 +1562,7 @@ static int htslang_load(char *limit_to, char *path) {
|
||||
if (strnotempty(extkey) && strnotempty(value)) {
|
||||
int len;
|
||||
char *buff;
|
||||
char *intkey;
|
||||
const char *intkey;
|
||||
|
||||
intkey = LANGINTKEY(extkey);
|
||||
|
||||
@@ -1601,7 +1570,7 @@ static int htslang_load(char *limit_to, char *path) {
|
||||
|
||||
/* Increment for multiple definitions */
|
||||
{
|
||||
char *test = LANGSEL(intkey);
|
||||
const char *test = LANGSEL(intkey);
|
||||
|
||||
if (strnotempty(test)) {
|
||||
if (loops == 0) {
|
||||
@@ -1655,7 +1624,7 @@ static int htslang_load(char *limit_to, char *path) {
|
||||
}
|
||||
|
||||
/* NOTE : also contains the "webhttrack" hack */
|
||||
static void conv_printf(char *from, char *to) {
|
||||
static void conv_printf(const char *from, char *to) {
|
||||
int i = 0, j = 0, len;
|
||||
|
||||
len = (int) strlen(from);
|
||||
@@ -1729,7 +1698,7 @@ static void LANG_DELETE(void) {
|
||||
}
|
||||
|
||||
// sélection de la langue
|
||||
static void LANG_INIT(char *path) {
|
||||
static void LANG_INIT(const char *path) {
|
||||
//CWinApp* pApp = AfxGetApp();
|
||||
//if (pApp) {
|
||||
/* pApp->GetProfileInt("Language","IntId",0); */
|
||||
@@ -1737,7 +1706,7 @@ static void LANG_INIT(char *path) {
|
||||
//}
|
||||
}
|
||||
|
||||
static int LANG_T(char *path, int l) {
|
||||
static int LANG_T(const char *path, int l) {
|
||||
if (l >= 0) {
|
||||
QLANG_T(l);
|
||||
htslang_load(NULL, path);
|
||||
@@ -1745,7 +1714,7 @@ static int LANG_T(char *path, int l) {
|
||||
return QLANG_T(-1); // 0=default (english)
|
||||
}
|
||||
|
||||
static int LANG_SEARCH(char *path, char *iso) {
|
||||
static int LANG_SEARCH(const char *path, const char *iso) {
|
||||
char lang_str[1024];
|
||||
int i = 0;
|
||||
int curr_lng = LANG_T(path, -1);
|
||||
@@ -1764,7 +1733,7 @@ static int LANG_SEARCH(char *path, char *iso) {
|
||||
return found;
|
||||
}
|
||||
|
||||
static int LANG_LIST(char *path, char *buffer) {
|
||||
static int LANG_LIST(const char *path, char *buffer, size_t size) {
|
||||
char lang_str[1024];
|
||||
int i = 0;
|
||||
int curr_lng = LANG_T(path, -1);
|
||||
@@ -1772,7 +1741,7 @@ static int LANG_LIST(char *path, char *buffer) {
|
||||
buffer[0] = '\0';
|
||||
do {
|
||||
QLANG_T(i);
|
||||
strcpybuff(lang_str, "LANGUAGE_NAME");
|
||||
strlcpybuff(lang_str, "LANGUAGE_NAME", size);
|
||||
htslang_load(lang_str, path);
|
||||
if (strlen(lang_str) > 0) {
|
||||
if (buffer[0])
|
||||
@@ -1794,28 +1763,26 @@ static int QLANG_T(int l) {
|
||||
return lng; // 0=default (english)
|
||||
}
|
||||
|
||||
static char *LANGSEL(char *name) {
|
||||
intptr_t adr = 0;
|
||||
|
||||
if (NewLangStr)
|
||||
if (!inthash_read(NewLangStr, name, &adr))
|
||||
adr = 0;
|
||||
if (adr) {
|
||||
return (char *) adr;
|
||||
const char* LANGSEL(const char* name) {
|
||||
inthash_value value;
|
||||
if (NewLangStr != NULL
|
||||
&& inthash_read_value(NewLangStr, name, &value) != 0
|
||||
&& value.ptr != NULL) {
|
||||
return (char*) value.ptr;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static char *LANGINTKEY(char *name) {
|
||||
intptr_t adr = 0;
|
||||
|
||||
if (NewLangStrKeys)
|
||||
if (!inthash_read(NewLangStrKeys, name, &adr))
|
||||
adr = 0;
|
||||
if (adr) {
|
||||
return (char *) adr;
|
||||
const char* LANGINTKEY(const char* name) {
|
||||
inthash_value value;
|
||||
if (NewLangStrKeys != NULL
|
||||
&& inthash_read_value(NewLangStrKeys, name, &value) != 0
|
||||
&& value.ptr != NULL) {
|
||||
return (char*) value.ptr;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/* *** Various functions *** */
|
||||
@@ -1848,7 +1815,7 @@ static int check_readinput(htsblk * r) {
|
||||
FD_SET(r->soc, &fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
select(r->soc + 1, &fds, NULL, NULL, &tv);
|
||||
select((int) r->soc + 1, &fds, NULL, NULL, &tv);
|
||||
if (FD_ISSET(r->soc, &fds))
|
||||
return 1;
|
||||
else
|
||||
|
||||
@@ -91,9 +91,9 @@ extern httrackp *global_opt;
|
||||
#define min(a,b) ((a)>(b)?(b):(a))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
extern int smallserver_setkey(char *key, char *value);
|
||||
extern int smallserver_setkeyint(char *key, LLint value);
|
||||
extern int smallserver_setkeyarr(char *key, int id, char *key2, char *value);
|
||||
extern int smallserver_setkey(const char *key, const char *value);
|
||||
extern int smallserver_setkeyint(const char *key, LLint value);
|
||||
extern int smallserver_setkeyarr(const char *key, int id, const char *key2, const char *value);
|
||||
|
||||
int htslang_init(void);
|
||||
int htslang_uninit(void);
|
||||
@@ -147,7 +147,7 @@ HTS_UNUSED static int check_readinput_t(T_SOC soc, int timeout) {
|
||||
FD_SET(soc, &fds);
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
select(soc + 1, &fds, NULL, NULL, &tv);
|
||||
select((int) soc + 1, &fds, NULL, NULL, &tv);
|
||||
if (FD_ISSET(soc, &fds))
|
||||
return 1;
|
||||
else
|
||||
|
||||
@@ -59,8 +59,9 @@ int hts_zunpack(char *filename, char *newfile) {
|
||||
char catbuff[CATBUFF_SIZE];
|
||||
FILE *const in = FOPEN(fconv(catbuff, sizeof(catbuff), filename), "rb");
|
||||
const int fd = in != NULL ? fileno(in) : -1;
|
||||
const int dup_fd = fd != -1 ? dup(fd) : -1;
|
||||
// Note: we must dup to be able to flose cleanly.
|
||||
gzFile gz = fd != -1 ? gzdopen(dup(fd), "rb") : NULL;
|
||||
const gzFile gz = dup_fd != -1 ? gzdopen(dup_fd, "rb") : NULL;
|
||||
|
||||
if (gz) {
|
||||
FILE *const fpout = FOPEN(fconv(catbuff, sizeof(catbuff), newfile), "wb");
|
||||
|
||||
@@ -38,6 +38,7 @@ Please visit our Website: http://www.httrack.com
|
||||
#ifndef _WIN32
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifndef HTS_DEF_FWSTRUCT_httrackp
|
||||
#define HTS_DEF_FWSTRUCT_httrackp
|
||||
@@ -65,6 +66,12 @@ typedef enum hts_log_type {
|
||||
typedef struct hts_stat_struct hts_stat_struct;
|
||||
#endif
|
||||
|
||||
/** Assert error callback. **/
|
||||
#ifndef HTS_DEF_FWSTRUCT_htsErrorCallback
|
||||
#define HTS_DEF_FWSTRUCT_htsErrorCallback
|
||||
typedef void (*htsErrorCallback) (const char *msg, const char *file, int line);
|
||||
#endif
|
||||
|
||||
/* Helpers for plugging callbacks
|
||||
requires: htsdefines.h */
|
||||
|
||||
@@ -111,6 +118,8 @@ HTSEXT_API const hts_stat_struct* hts_get_stats(httrackp * opt);
|
||||
HTSEXT_API void set_wrappers(httrackp * opt); /* LEGACY */
|
||||
HTSEXT_API int plug_wrapper(httrackp * opt, const char *moduleName,
|
||||
const char *argv);
|
||||
HTSEXT_API void hts_set_error_callback(htsErrorCallback handler);
|
||||
HTSEXT_API htsErrorCallback hts_get_error_callback(void);
|
||||
|
||||
/* Logging */
|
||||
HTSEXT_API int hts_log(httrackp * opt, const char *prefix, const char *msg);
|
||||
@@ -118,6 +127,9 @@ HTSEXT_API void hts_log_print(httrackp * opt, int type, const char *format,
|
||||
...) HTS_PRINTF_FUN(3, 4);
|
||||
HTSEXT_API void hts_log_vprint(httrackp * opt, int type, const char *format,
|
||||
va_list args);
|
||||
HTSEXT_API void hts_set_log_vprint_callback(void (*callback)(httrackp * opt,
|
||||
int type,
|
||||
const char *format, va_list args));
|
||||
|
||||
/* Infos */
|
||||
HTSEXT_API const char *hts_get_version_info(httrackp * opt);
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.3\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.8\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
PreprocessorDefinitions="WIN32;_CONSOLE;HTS_ANALYSTE_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
@@ -152,7 +152,7 @@
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.3\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.8\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
PreprocessorDefinitions="WIN32;_CONSOLE;HTS_ANALYSTE_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
@@ -246,7 +246,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/Zm200 "
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.3\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.8\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;HTS_ANALYSTE_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="true"
|
||||
@@ -343,7 +343,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/Zm200 "
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.3\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.8\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;HTS_ANALYSTE_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="true"
|
||||
@@ -440,7 +440,7 @@
|
||||
AdditionalOptions="/Zm200 "
|
||||
Optimization="3"
|
||||
InlineFunctionExpansion="2"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.3\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.8\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;HTS_ANALYSTE_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
@@ -535,7 +535,7 @@
|
||||
AdditionalOptions="/Zm200 "
|
||||
Optimization="3"
|
||||
InlineFunctionExpansion="2"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.3\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
AdditionalIncludeDirectories=""C:\Dev\zlib-1.2.8\";"C:\Dev\openssl-1.0.1e\include";C:\Dev\Winhttrack"
|
||||
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;HTS_ANALYSTE_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
|
||||
@@ -226,18 +226,17 @@ static int linputsoc_t(T_SOC soc, char *s, int max, int timeout) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int gethost(const char *hostname, SOCaddr * server, size_t server_size) {
|
||||
static int gethost(const char *hostname, SOCaddr * server) {
|
||||
if (hostname != NULL && *hostname != '\0') {
|
||||
#if HTS_INET6==0
|
||||
/*
|
||||
ipV4 resolver
|
||||
*/
|
||||
t_hostent *hp = gethostbyname(hostname);
|
||||
struct hostent *hp = gethostbyname(hostname);
|
||||
|
||||
if (hp != NULL) {
|
||||
if (hp->h_length) {
|
||||
SOCaddr_copyaddr(*server, server_size, hp->h_addr_list[0],
|
||||
hp->h_length);
|
||||
SOCaddr_copyaddr2(*server, hp->h_addr_list[0], hp->h_length);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -256,13 +255,13 @@ static int gethost(const char *hostname, SOCaddr * server, size_t server_size) {
|
||||
hints.ai_family = PF_INET6;
|
||||
else
|
||||
#endif
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
if (getaddrinfo(hostname, NULL, &hints, &res) == 0) {
|
||||
if (res) {
|
||||
if ((res->ai_addr) && (res->ai_addrlen)) {
|
||||
SOCaddr_copyaddr(*server, server_size, res->ai_addr, res->ai_addrlen);
|
||||
SOCaddr_copyaddr2(*server, res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
return 1;
|
||||
}
|
||||
@@ -276,7 +275,7 @@ static int gethost(const char *hostname, SOCaddr * server, size_t server_size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static String getip(SOCaddr * server, int serverLen) {
|
||||
static String getip(SOCaddr * server) {
|
||||
String s = STRING_EMPTY;
|
||||
|
||||
#if HTS_INET6==0
|
||||
@@ -291,7 +290,7 @@ static String getip(SOCaddr * server, int serverLen) {
|
||||
proxytrack_print_log(CRITICAL, "memory exhausted");
|
||||
return s;
|
||||
}
|
||||
SOCaddr_inetntoa(dotted, sizeMax, *server, serverLen);
|
||||
SOCaddr_inetntoa(dotted, sizeMax, *server);
|
||||
sprintf(dotted + strlen(dotted), ":%d", port);
|
||||
StringAttach(&s, &dotted);
|
||||
return s;
|
||||
@@ -299,18 +298,15 @@ static String getip(SOCaddr * server, int serverLen) {
|
||||
|
||||
static T_SOC smallserver_init(const char *adr, int port, int family) {
|
||||
SOCaddr server;
|
||||
size_t server_size = sizeof(server);
|
||||
|
||||
memset(&server, 0, sizeof(server));
|
||||
SOCaddr_initany(server, server_size);
|
||||
if (gethost(adr, &server, server_size)) { // host name
|
||||
SOCaddr_initany(server);
|
||||
if (gethost(adr, &server)) { // host name
|
||||
T_SOC soc = INVALID_SOCKET;
|
||||
|
||||
if ((soc =
|
||||
(T_SOC) socket(SOCaddr_sinfamily(server), family,
|
||||
0)) != INVALID_SOCKET) {
|
||||
SOCaddr_initport(server, port);
|
||||
if (bind(soc, (struct sockaddr *) &server, (int) server_size) == 0) {
|
||||
if (bind(soc, &SOCaddr_sockaddr(server), SOCaddr_size(server)) == 0) {
|
||||
if (family != SOCK_STREAM || listen(soc, 10) >= 0) {
|
||||
return soc;
|
||||
} else {
|
||||
@@ -1320,12 +1316,12 @@ static void proxytrack_process_HTTP(PT_Indexes indexes, T_SOC soc_c) {
|
||||
/* */
|
||||
String ip = STRING_EMPTY;
|
||||
SOCaddr serverClient;
|
||||
SOClen lenServerClient = (int) sizeof(serverClient);
|
||||
SOClen lenServerClient = SOCaddr_capacity(serverClient);
|
||||
|
||||
memset(&serverClient, 0, sizeof(serverClient));
|
||||
if (getsockname
|
||||
(soc_c, (struct sockaddr *) &serverClient, &lenServerClient) == 0) {
|
||||
ip = getip(&serverClient, lenServerClient);
|
||||
(soc_c, &SOCaddr_sockaddr(serverClient), &lenServerClient) == 0) {
|
||||
ip = getip(&serverClient);
|
||||
} else {
|
||||
StringCopy(ip, "unknown");
|
||||
}
|
||||
@@ -1571,14 +1567,14 @@ static int proxytrack_start_ICP(PT_Indexes indexes, T_SOC soc) {
|
||||
return -1;
|
||||
}
|
||||
while(soc != INVALID_SOCKET) {
|
||||
struct sockaddr clientAddr;
|
||||
SOClen clientAddrLen = sizeof(struct sockaddr);
|
||||
SOCaddr clientAddr;
|
||||
SOClen clientAddrLen = SOCaddr_capacity(clientAddr);
|
||||
int n;
|
||||
|
||||
memset(&clientAddr, 0, sizeof(clientAddr));
|
||||
n =
|
||||
recvfrom(soc, (char *) buffer, bufferSize, 0, &clientAddr,
|
||||
&clientAddrLen);
|
||||
n = recvfrom(soc, (char *) buffer, bufferSize, 0,
|
||||
&SOCaddr_sockaddr(clientAddr),
|
||||
&clientAddrLen);
|
||||
if (n != -1) {
|
||||
const char *LogRequest = "ERROR";
|
||||
const char *LogReply = "ERROR";
|
||||
@@ -1621,11 +1617,11 @@ static int proxytrack_start_ICP(PT_Indexes indexes, T_SOC soc) {
|
||||
UrlRequestSize = (unsigned int) strlen((char *) UrlRequest);
|
||||
LogRequest = "ICP_OP_QUERY";
|
||||
if (indexes == NULL) {
|
||||
ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_DENIED,
|
||||
ICP_reply(&SOCaddr_sockaddr(clientAddr), clientAddrLen, soc, ICP_OP_DENIED,
|
||||
Version, 0, Request_Number, 0, 0, 0, UrlRequest);
|
||||
LogReply = "ICP_OP_DENIED";
|
||||
} else if (PT_LookupIndex(indexes, (char*) UrlRequest)) {
|
||||
ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT,
|
||||
ICP_reply(&SOCaddr_sockaddr(clientAddr), clientAddrLen, soc, ICP_OP_HIT,
|
||||
Version, 0, Request_Number, 0, 0, 0, UrlRequest);
|
||||
LogReply = "ICP_OP_HIT";
|
||||
} else {
|
||||
@@ -1637,7 +1633,7 @@ static int proxytrack_start_ICP(PT_Indexes indexes, T_SOC soc) {
|
||||
if (UrlRedirect != NULL) {
|
||||
sprintf(UrlRedirect, "%s/", UrlRequest);
|
||||
if (PT_LookupIndex(indexes, UrlRedirect)) { /* We'll generate a redirect */
|
||||
ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT,
|
||||
ICP_reply(&SOCaddr_sockaddr(clientAddr), clientAddrLen, soc, ICP_OP_HIT,
|
||||
Version, 0, Request_Number, 0, 0, 0,
|
||||
UrlRequest);
|
||||
LogReply = "ICP_OP_HIT";
|
||||
@@ -1648,7 +1644,7 @@ static int proxytrack_start_ICP(PT_Indexes indexes, T_SOC soc) {
|
||||
}
|
||||
}
|
||||
/* We won't retrive the cache MISS online, no way! */
|
||||
ICP_reply(&clientAddr, clientAddrLen, soc,
|
||||
ICP_reply(&SOCaddr_sockaddr(clientAddr), clientAddrLen, soc,
|
||||
ICP_OP_MISS_NOFETCH, Version, 0, Request_Number,
|
||||
0, 0, 0, UrlRequest);
|
||||
LogReply = "ICP_OP_MISS_NOFETCH";
|
||||
@@ -1660,24 +1656,24 @@ static int proxytrack_start_ICP(PT_Indexes indexes, T_SOC soc) {
|
||||
UrlRequest = &Payload[4];
|
||||
LogRequest = "ICP_OP_QUERY";
|
||||
LogReply = "ICP_OP_QUERY";
|
||||
ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_SECHO,
|
||||
ICP_reply(&SOCaddr_sockaddr(clientAddr), clientAddrLen, soc, ICP_OP_SECHO,
|
||||
Version, 0, Request_Number, 0, 0, 0, UrlRequest);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LogRequest = "NOTIMPLEMENTED";
|
||||
LogReply = "ICP_OP_ERR";
|
||||
ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version,
|
||||
ICP_reply(&SOCaddr_sockaddr(clientAddr), clientAddrLen, soc, ICP_OP_ERR, Version,
|
||||
0, Request_Number, 0, 0, 0, NULL);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, 2, 0,
|
||||
ICP_reply(&SOCaddr_sockaddr(clientAddr), clientAddrLen, soc, ICP_OP_ERR, 2, 0,
|
||||
Request_Number, 0, 0, 0, NULL);
|
||||
}
|
||||
} /* Ignored (RFC2186) */
|
||||
} else {
|
||||
ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version, 0,
|
||||
ICP_reply(&SOCaddr_sockaddr(clientAddr), clientAddrLen, soc, ICP_OP_ERR, Version, 0,
|
||||
Request_Number, 0, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
@@ -1691,7 +1687,7 @@ static int proxytrack_start_ICP(PT_Indexes indexes, T_SOC soc) {
|
||||
SOCaddr_copyaddr(serverClient, lenServerClient, &clientAddr,
|
||||
clientAddrLen);
|
||||
if (lenServerClient > 0) {
|
||||
ip = getip(&serverClient, lenServerClient);
|
||||
ip = getip(&clientAddr);
|
||||
} else {
|
||||
StringCopy(ip, "unknown");
|
||||
}
|
||||
|
||||
@@ -13,3 +13,9 @@ bash crawl-test.sh \
|
||||
httrack 'http://ut.httrack.com/unicode-links/idna.html' \
|
||||
'+*.ut.httrack.com/*' --robots=0
|
||||
|
||||
# unicode tests (bogus links)
|
||||
bash crawl-test.sh \
|
||||
--errors 0 --files 1 \
|
||||
--found 'ut.httrack.com/unicode-links/idna_bogus.html' \
|
||||
httrack 'http://ut.httrack.com/unicode-links/idna_bogus.html' \
|
||||
'-*' --robots=0
|
||||
|
||||
Reference in New Issue
Block a user