99 Commits

Author SHA1 Message Date
Xavier Roche
1f8a15c76f 3.48.9 tag is back 2014-06-05 15:59:09 +00:00
Xavier Roche
40f237fe9c Fixed "this decimal constant is unsigned only in ISO C90" 2014-06-04 19:53:07 +00:00
Xavier Roche
04cfb2db0e Updated man 2014-06-04 17:41:42 +00:00
Xavier Roche
bdbf66b45c Updated configure 2014-06-04 17:10:40 +00:00
Xavier Roche
6bace27858 3.48.10 2014-06-04 17:06:43 +00:00
Xavier Roche
7d3d496a7f 3.48-10 2014-06-04 17:02:44 +00:00
Xavier Roche
7826a49f59 Do not depend on SetDllDirectory (Windows 2003) as it breaks Windows 2000
* closes: #45
2014-06-04 16:10:38 +00:00
Xavier Roche
ed79961b7a Potential fix for htshash.c:330 assertion failure: "error invalidating hash entry" 2014-06-03 16:26:25 +00:00
Xavier Roche
d3c14c9d1f Missing string.h (moe) 2014-05-30 16:09:02 +00:00
Xavier Roche
7026ba7c7b Better "too many links" reporting. 2014-05-29 18:10:14 +00:00
Xavier Roche
abe98f238d Allocation failure handling. 2014-05-29 17:58:05 +00:00
Xavier Roche
8dd39bc909 Take in account opt->maxlink is non-zero 2014-05-29 17:29:02 +00:00
Xavier Roche
17ec3ecd6b Fixed regression over ./ 2014-05-29 16:14:57 +00:00
Xavier Roche
c7636d4f90 tr -d '\r' 2014-05-29 16:03:04 +00:00
Xavier Roche
3a7e594166 Fixed API change. 2014-05-29 15:57:57 +00:00
Xavier Roche
b88395a16c Unused function. 2014-05-29 15:53:30 +00:00
Xavier Roche
4f5776a8fa Big cleanup: introducing cleaner lien_adrfilsave and lien_adrfil structures holding address/uri or address/uri/filename rather than passing opaque char* of unknown size. 2014-05-29 15:42:53 +00:00
Xavier Roche
8adeadbdb6 Removed duplicate opt->lien_tot and opt->liens members in some functions. 2014-05-29 09:41:59 +00:00
Xavier Roche
c64b8d6e88 Fixes. 2014-05-29 09:34:37 +00:00
Xavier Roche
194ebad4c6 Added off_t_to_size_t() 2014-05-29 08:30:43 +00:00
Xavier Roche
ae6d05fbb3 Allocation cleanup (why "+2", why ?) 2014-05-29 08:20:07 +00:00
Xavier Roche
803f7b5a33 Added -Wformat-nonliteral flag. 2014-05-28 19:11:04 +00:00
Xavier Roche
f919aab408 Added assert 2014-05-28 19:05:31 +00:00
Xavier Roche
0238301aca Replaced sprintf() by hts_template_format_str() 2014-05-28 19:03:26 +00:00
Xavier Roche
3864a45388 Fixed NULL terminated string. 2014-05-28 19:03:07 +00:00
Xavier Roche
5e248cc4e3 Rewrite string template formatting to be format-injection proof. 2014-05-28 18:58:59 +00:00
Xavier Roche
473baf7f95 Fixed heap crawl overflow 2014-05-28 18:41:59 +00:00
Xavier Roche
27752e368c Rewrite template formatting to be format-injection proof. 2014-05-28 18:31:40 +00:00
Xavier Roche
37187f967f Fixed %%% 2014-05-28 18:27:45 +00:00
Xavier Roche
1d07610320 Added AM_PROG_CC_C_O and AM_PROG_LIBTOOL
Removed unused CXX

added the following default compiler flags:
  -Wdeclaration-after-statement
  -Wsequence-point
  -Wparentheses
  -Winit-self
  -Wuninitialized
  -Wformat
  -fstrict-aliasing -Wstrict-aliasing=2

added the following default linker flags:
  -Wl,--discard-all
  -Wl,--no-undefined

Depending on autoconf-archive because using AX_CHECK_COMPILE_FLAG and AX_CHECK_LINK_FLAG
2014-05-28 17:55:49 +00:00
Xavier Roche
49304bbe8f Bad md5. 2014-05-28 17:41:42 +00:00
Xavier Roche
11e069aa07 Really fixed. 2014-05-28 17:06:47 +00:00
Xavier Roche
0c7a0274ca Fixed build. 2014-05-28 16:58:37 +00:00
Xavier Roche
f3a4a20750 Fixed const T ** not being castable to const T ** 2014-05-28 16:51:56 +00:00
Xavier Roche
e090cd9ccf Added MD5 self-test 2014-05-28 16:50:47 +00:00
Xavier Roche
1bebff2697 Fixed dirty uint32_t cast leading to aliasing issues. 2014-05-28 16:36:24 +00:00
Xavier Roche
c7fac4dbca Added Vcs-Browser and Vcs-Svn fields to debian/control 2014-05-28 16:34:06 +00:00
Xavier Roche
0b52cac218 Cleanup, const correctness 2014-05-27 18:55:13 +00:00
Xavier Roche
43b457203b Fixed help option, and too long help line (man: "cannot adjust line") 2014-05-27 17:45:18 +00:00
Xavier Roche
fdcff762f6 Rewritten UTF8 writer to avoir spurious GCC 4.8.3 warnings. 2014-05-27 16:35:57 +00:00
Xavier Roche
c3987aca71 Export may_unknown and guess_httptype 2014-05-27 16:05:54 +00:00
Xavier Roche
f67a86657b tr -d '\r' 2014-05-27 16:05:28 +00:00
Xavier Roche
01edfd6d1e Fixed symbol import. 2014-05-27 16:05:09 +00:00
Xavier Roche
a300785d5e tr -d '\r' 2014-05-26 19:32:34 +00:00
Xavier Roche
5364514f34 Big links heap handling cleanup, and removed very old and legacy macros 2014-05-26 19:27:46 +00:00
Xavier Roche
f078a39677 Minizip warning fixes. 2014-05-24 11:57:25 +00:00
Xavier Roche
65454f4ff1 Fixed EXTRA_DIST 2014-05-24 11:38:11 +00:00
Xavier Roche
15813b5380 Removed ChangeLogUnzip 2014-05-24 11:31:17 +00:00
Xavier Roche
033ce293b8 Fixed minizip. 2014-05-24 08:37:21 +00:00
Xavier Roche
d1913325e4 Missing zflush_file member. 2014-05-24 08:17:08 +00:00
Xavier Roche
882578ed9a Upgraded to minizip 1.1 from zlib 1.2.8 2014-05-24 07:56:11 +00:00
Xavier Roche
1ec8b5fb9e No diff. 2014-05-24 07:50:51 +00:00
Xavier Roche
796c62f07c Diff are better. 2014-05-24 07:45:12 +00:00
Xavier Roche
cefcc04266 "const correctness" cleanup
added the following default flags:
  -Wformat
  -Wformat-security
  -Wmultichar
  -Wwrite-strings
fixed several other warnings
2014-05-23 21:33:43 +00:00
Xavier Roche
6ba50a2001 Added symbol visibility features to the build to hide internal symbols (GCC) 2014-05-23 15:28:55 +00:00
Xavier Roche
9315f64b6e 3.48.9 (autoconf) 2014-05-23 15:24:50 +00:00
Xavier Roche
feb2a02cc2 3.48.9-1 changelog 2014-05-23 15:23:17 +00:00
Xavier Roche
24ff04fdb7 3.48.9 2014-05-21 17:21:29 +00:00
Xavier Roche
72e0c0601b Cleaner dup 2014-05-21 17:01:30 +00:00
Xavier Roche
b72741ddc9 tr -d '\r' 2014-05-19 19:37:40 +00:00
Xavier Roche
1edfda507d Added unit test for issue #44 2014-05-19 19:24:06 +00:00
Xavier Roche
4a62c84479 char* => const char* 2014-05-19 19:17:50 +00:00
Xavier Roche
595d446470 Added strlcpybuff() macro. 2014-05-19 19:15:16 +00:00
Xavier Roche
0474c596b6 Fixed segOutputSize < segSize assertion fails at htscharset.c:993
* closes:#44
2014-05-19 19:12:27 +00:00
Xavier Roche
9f23ea7980 Fixed __builtin___strncat_chk warning 2014-05-18 14:05:08 +00:00
Xavier Roche
fe1ec5b0f6 Removed unused variable. 2014-05-18 14:02:06 +00:00
Xavier Roche
fd1ab669ad tr -d '\r' 2014-05-18 13:55:54 +00:00
Xavier Roche
34788bb7f6 Backlog for web server to 10. 2014-05-18 13:55:47 +00:00
Xavier Roche
03edb3eac8 Cleanup in callbacks. 2014-05-18 13:43:09 +00:00
Xavier Roche
fe7ea8b140 Big cleanup in network address and dns functions:
* removed t_fullhostent insanity
  * removed (struct sockaddr*) casts
  * use SOCaddr everywhere rather than raw struct hostent*
2014-05-18 13:11:40 +00:00
Xavier Roche
1fd27d74af libtool: in_port_t and sa_family_t 2014-05-18 10:59:07 +00:00
Xavier Roche
08a17f31d4 Removed size member from SOCaddr 2014-05-18 10:53:29 +00:00
Xavier Roche
6c8b76e531 Cleanup in socket handling (less ugly casts!) 2014-05-18 09:49:24 +00:00
Xavier Roche
66c8cc32aa Illegal use of strnlen(..., (size_t) -1) 2014-05-17 13:55:17 +00:00
Xavier Roche
2209c7bdd8 Anonymous logging. 2014-05-17 13:29:45 +00:00
Xavier Roche
cb0460ddcb Added hts_set_log_vprint_callback() definition 2014-05-17 13:21:03 +00:00
Xavier Roche
fb9e02ffb9 Added hts_set_log_vprint_callback() 2014-05-17 13:20:42 +00:00
Xavier Roche
ac779cb6a0 Fixed potentiel overrun if the user injects a buggy user-defined structure with a non-terminated %[] 2014-05-17 12:31:37 +00:00
Xavier Roche
0073d3ad05 tr -d '\r' 2014-05-15 19:44:28 +00:00
Xavier Roche
638cc96917 Added some asserts for Android. 2014-05-15 19:33:38 +00:00
Xavier Roche
c6e0ad4bce Cosmetic. 2014-05-15 19:27:29 +00:00
Xavier Roche
c457788a14 Compile-time checks. 2014-05-15 19:25:27 +00:00
Xavier Roche
216005d33a Fixed uint64_t vs. long long int 2014-05-15 19:24:56 +00:00
Xavier Roche
59008af067 Removed unused variable. 2014-05-15 17:26:46 +00:00
Xavier Roche
3059bd6f53 3.48.8-1 2014-05-15 17:22:16 +00:00
Xavier Roche
e5b3c85156 3.48.8 2014-05-15 17:08:29 +00:00
Xavier Roche
843faaf83d WIN32: zlib 1.2.8 2014-05-15 17:06:59 +00:00
Xavier Roche
75969b1147 Cosmetic 2014-05-14 20:27:55 +00:00
Xavier Roche
6ad604624d Fixed macro. 2014-05-14 20:20:01 +00:00
Xavier Roche
c05f54ae04 Clean hts_set_error_callback() and hts_get_error_callback() 2014-05-14 20:12:42 +00:00
Xavier Roche
ae1db762e7 Missing htsCallbackErr definition 2014-05-14 19:51:33 +00:00
Xavier Roche
16aec722bf 3.48.7 2014-05-14 17:57:18 +00:00
Xavier Roche
4ff55249ed 3.48.7 2014-05-14 17:51:09 +00:00
Xavier Roche
fea8122ed3 Fixed hashtable corruption because of dirty code directly modifying the host address in memory, leading to have hashtable positions not anymore valid.
This issue was especially triggered when a redirect was processed ("Warning moved treated for .." messages)
  * closes: #43
2014-05-14 17:48:04 +00:00
Xavier Roche
7323230eb3 Added debug logging facility. 2014-05-14 17:45:51 +00:00
Xavier Roche
c9f656fdeb Better stdarg.h 2014-05-13 20:12:10 +00:00
Xavier Roche
042525a1db #include <stdarg.h> 2014-05-13 20:11:41 +00:00
Xavier Roche
3fde59c090 #include <stdarg.h> 2014-05-13 20:11:02 +00:00
Xavier Roche
edaaa73328 #include <stdarg.h> 2014-05-13 20:08:53 +00:00
31 changed files with 781 additions and 684 deletions

View File

@@ -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
View File

@@ -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\\"

View File

@@ -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
View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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';

View File

@@ -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)) {

View File

@@ -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"

View File

@@ -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");
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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"

View File

@@ -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

View File

@@ -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__);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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");

View File

@@ -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);

View File

@@ -53,7 +53,7 @@
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="&quot;C:\Dev\zlib-1.2.3\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;C:\Dev\Winhttrack"
AdditionalIncludeDirectories="&quot;C:\Dev\zlib-1.2.8\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;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="&quot;C:\Dev\zlib-1.2.3\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;C:\Dev\Winhttrack"
AdditionalIncludeDirectories="&quot;C:\Dev\zlib-1.2.8\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;C:\Dev\Winhttrack"
PreprocessorDefinitions="WIN32;_CONSOLE;HTS_ANALYSTE_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@@ -246,7 +246,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/Zm200 "
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Dev\zlib-1.2.3\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;C:\Dev\Winhttrack"
AdditionalIncludeDirectories="&quot;C:\Dev\zlib-1.2.8\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;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="&quot;C:\Dev\zlib-1.2.3\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;C:\Dev\Winhttrack"
AdditionalIncludeDirectories="&quot;C:\Dev\zlib-1.2.8\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;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="&quot;C:\Dev\zlib-1.2.3\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;C:\Dev\Winhttrack"
AdditionalIncludeDirectories="&quot;C:\Dev\zlib-1.2.8\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;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="&quot;C:\Dev\zlib-1.2.3\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;C:\Dev\Winhttrack"
AdditionalIncludeDirectories="&quot;C:\Dev\zlib-1.2.8\&quot;;&quot;C:\Dev\openssl-1.0.1e\include&quot;;C:\Dev\Winhttrack"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;HTS_ANALYSTE_CONSOLE;_CRT_SECURE_NO_WARNINGS"
StringPooling="true"
RuntimeLibrary="2"

View File

@@ -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");
}

View File

@@ -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