31 Commits
3.48.3 ... 3.47

Author SHA1 Message Date
Xavier Roche
146d2e8981 Merged revisions 878 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r878 | roche | 2013-09-24 07:51:21 +0200 (mar., 24 sept. 2013) | 3 lines
  
  Do not depend anymore on automake1.9, but automake (see http://lists.debian.org/debian-devel/2013/05/msg01459.html)
........
2013-09-24 05:53:16 +00:00
Xavier Roche
ceda82f4fd 3.47.27 2013-09-15 09:09:28 +00:00
Xavier Roche
f6f01eaa96 Fixed license 2013-09-15 08:33:55 +00:00
Xavier Roche
47ca31b627 Fixed logging level (especially for robots.txt rules) 2013-09-15 08:33:31 +00:00
Xavier Roche
f06bd4cd7b Merged revisions 865 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r865 | roche | 2013-09-14 11:33:39 +0200 (sam., 14 sept. 2013) | 3 lines
  
  Also remove these commands in the help
........
2013-09-14 09:38:10 +00:00
Xavier Roche
f4b879adc9 Merged revisions 851,853,855-857,861-862 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r851 | roche | 2013-09-09 19:20:34 +0200 (lun., 09 sept. 2013) | 3 lines
  
  Fixed Keywords field in desktop files (Sebastian Pipping)
........
  r853 | roche | 2013-09-13 17:54:23 +0200 (ven., 13 sept. 2013) | 4 lines
  
  Fixed FSF GPL reference (postal address removed, added website)
  Fixed year notice
........
  r855 | roche | 2013-09-13 18:08:40 +0200 (ven., 13 sept. 2013) | 3 lines
  
  AUTHORS should be 644
........
  r856 | roche | 2013-09-13 18:12:52 +0200 (ven., 13 sept. 2013) | 3 lines
  
  Replaced AM_PROG_LIBTOOL by LT_INIT
........
  r857 | roche | 2013-09-13 18:13:02 +0200 (ven., 13 sept. 2013) | 3 lines
  
  Updated man
........
  r861 | roche | 2013-09-13 21:21:03 +0200 (ven., 13 sept. 2013) | 3 lines
  
  Fixed license and copyright
........
  r862 | roche | 2013-09-13 21:26:08 +0200 (ven., 13 sept. 2013) | 3 lines
  
  Fixed man
........
2013-09-13 19:29:17 +00:00
Xavier Roche
e5f8882c06 Backported r841
Fixed DNS stuck with unresolvable hosts.
2013-09-06 20:40:20 +00:00
Xavier Roche
09fab9362c 3.47.26 2013-09-06 19:55:32 +00:00
Xavier Roche
36e15496c9 Merged revisions 831-833 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r831 | roche | 2013-09-06 18:55:20 +0200 (ven., 06 sept. 2013) | 3 lines
  
  Fixed a little bit the infamous DNS cache
........
  r832 | roche | 2013-09-06 19:32:04 +0200 (ven., 06 sept. 2013) | 3 lines
  
  Fixed dangling pointer which probably explain the crash at libhttrack.so:0x639d0
........
  r833 | roche | 2013-09-06 20:51:07 +0200 (ven., 06 sept. 2013) | 3 lines
  
  Finished to cleanup the DNS cache.
........
2013-09-06 19:46:42 +00:00
Xavier Roche
411965963f Merged revisions 415 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r415 | roche | 2013-06-30 09:57:07 +0200 (dim., 30 juin 2013) | 3 lines
  
  Added Keywords entries for desktop files.
........
2013-09-06 19:46:09 +00:00
Xavier Roche
eaf4973b4c 3.47.25-1 2013-09-01 14:49:51 +00:00
Xavier Roche
4ae051f6e8 Merged revisions 824-825 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r824 | roche | 2013-09-01 15:58:23 +0200 (dim., 01 sept. 2013) | 3 lines
  
  Fixed content-disposition NOT taken in account (Stephan Matthiesen) except when updating/continuing.
........
  r825 | roche | 2013-09-01 16:05:08 +0200 (dim., 01 sept. 2013) | 3 lines
  
  Updated history
........
2013-09-01 14:44:16 +00:00
Xavier Roche
c118b8f1ea 3.47.24 2013-08-23 16:29:40 +00:00
Xavier Roche
f49b20df54 Merged revisions 764 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r764 | roche | 2013-08-22 18:21:47 +0200 (jeu., 22 août 2013) | 4 lines
  
  Fixed regression introduced in recent code cleanup
  The relative "luck" was that the {{{i < s[i] != '\0'}}} expression is actually working for small strings with standard ascii characters (...)
........
2013-08-22 18:01:49 +00:00
Xavier Roche
d40af55729 3.47.23 2013-08-17 10:27:03 +00:00
Xavier Roche
c7db0e2824 Merged revisions 428,704,706-709 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r428 | roche | 2013-07-05 21:42:21 +0200 (ven., 05 juil. 2013) | 3 lines
  
  Croatian translation by Dominko Aždajić (domazd at mail dot ru)
........
  r704 | roche | 2013-08-16 15:10:20 +0200 (ven., 16 août 2013) | 3 lines
  
  Make "Unexpected 412/416 error" non-fatal until I find out why in hell this bug is still out there.
........
  r706 | roche | 2013-08-17 09:43:45 +0200 (sam., 17 août 2013) | 3 lines
  
  A bit of cleanup in really old code (strlen() in loops, shame on me, but hey, this code is 15 years old)
........
  r707 | roche | 2013-08-17 09:57:44 +0200 (sam., 17 août 2013) | 3 lines
  
  Some cleanup in obviously wrong 15-year-old code.
........
  r708 | roche | 2013-08-17 09:57:53 +0200 (sam., 17 août 2013) | 3 lines
  
  Fixed definition.
........
  r709 | roche | 2013-08-17 11:09:13 +0200 (sam., 17 août 2013) | 3 lines
  
  Fixed issue 25 regarding un-encoding of characters such as # in the filename.
........
2013-08-17 10:14:38 +00:00
Xavier Roche
e542b0c49a Fixed history 2013-08-11 19:59:42 +00:00
Xavier Roche
617aeb1e22 3.47.22 2013-08-11 19:58:57 +00:00
Xavier Roche
7b470aa3a6 Merged revisions 528 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r528 | roche | 2013-08-05 12:07:40 +0200 (lun., 05 août 2013) | 3 lines
  
  Allow -m,10000 variant
........
2013-08-05 10:08:07 +00:00
Xavier Roche
3f8efc9209 Merged revisions 493 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r493 | roche | 2013-07-15 21:12:46 +0200 (lun., 15 juil. 2013) | 4 lines
  
  Fixed "Wildcard domains in cookies do not match" (alexei dot co at gmail dot com )
    * closes issue #19
........
2013-07-15 20:05:09 +00:00
Xavier Roche
25e296c53a Merged revisions 494 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r494 | roche | 2013-07-15 21:19:24 +0200 (lun., 15 juil. 2013) | 5 lines
  
  Fixed buggy referer while parsing: the referer of all links in the page is the current page being parsed, NOT the parent page. (alexei dot co at gmail dot com)
    * closes: issue #20
........
2013-07-15 20:04:51 +00:00
Xavier Roche
98db40d5e5 Merged revisions 495 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r495 | roche | 2013-07-15 21:21:25 +0200 (lun., 15 juil. 2013) | 3 lines
  
  Added .torrent => application/x-bittorrent built-in MIME type (alexei dot co at gmail dot com)
........
2013-07-15 20:04:40 +00:00
Xavier Roche
42010f42e7 Merged revisions 496 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r496 | roche | 2013-07-15 21:54:17 +0200 (lun., 15 juil. 2013) | 3 lines
  
  CLEANFILES = check-network_sh.cache
........
2013-07-15 20:04:28 +00:00
Xavier Roche
df67c753f0 Merged revisions 497 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r497 | roche | 2013-07-15 21:56:37 +0200 (lun., 15 juil. 2013) | 3 lines
  
  Ignore *.in, aclocal.m4 and configure
........
2013-07-15 20:03:47 +00:00
Xavier Roche
e1275ce47d Merged revisions 426 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r426 | roche | 2013-07-05 21:28:02 +0200 (ven., 05 juil. 2013) | 3 lines
  
  Russian translation fixes by Oleg Komarov (komoleg at mail dot ru)
........
2013-07-05 19:28:31 +00:00
Xavier Roche
d7359881ca Merged revisions 424 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r424 | roche | 2013-07-05 20:48:22 +0200 (ven., 05 juil. 2013) | 3 lines
  
  Fixed ut
........
2013-07-05 18:49:28 +00:00
Xavier Roche
d93f93510d Merged revisions 422 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r422 | roche | 2013-07-05 20:36:20 +0200 (ven., 05 juil. 2013) | 3 lines
  
  Fixed escaping
........
2013-07-05 18:36:58 +00:00
Xavier Roche
cc76389094 3.47.21 2013-07-05 18:20:48 +00:00
Xavier Roche
b3942b9878 Merged revisions 419 via svnmerge from
http://proliant/svn/httrack/trunk

........
  r419 | roche | 2013-07-05 19:53:54 +0200 (ven., 05 juil. 2013) | 4 lines
  
  Do not unescape '+' before the query string
  Fixed issue 18
........
2013-07-05 17:59:26 +00:00
Xavier Roche
fa33acc27e 3.47.20 2013-06-28 17:59:54 +00:00
Xavier Roche
31b5a463fd Created 3.47 branch. 2013-06-19 18:23:50 +00:00
89 changed files with 5303 additions and 5760 deletions

View File

@@ -54,8 +54,7 @@ subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
compile config.guess config.sub depcomp install-sh ltmain.sh \
missing
config.guess config.sub depcomp install-sh ltmain.sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/check_zlib.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \

142
compile
View File

@@ -1,142 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
scriptversion=2005-05-14.22
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand `-c -o'.
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file `INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
esac
ofile=
cfile=
eat=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we strip `-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@@ -63,6 +63,12 @@
/* Check for libsocket */
#undef LIBSOCKET
/* LLint format */
#undef LLINT_FORMAT
/* LLint type */
#undef LLINT_TYPE
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR

233
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.3.
# Generated by GNU Autoconf 2.69 for httrack 3.47.27.
#
# 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.3'
PACKAGE_STRING='httrack 3.48.3'
PACKAGE_VERSION='3.47.27'
PACKAGE_STRING='httrack 3.47.27'
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.3 to adapt to many kinds of systems.
\`configure' configures httrack 3.47.27 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.3:";;
short | recursive ) echo "Configuration of httrack 3.47.27:";;
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.3
httrack configure 3.47.27
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.3, which was
It was created by httrack $as_me 3.47.27, 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.3'
VERSION='3.47.27'
cat >>confdefs.h <<_ACEOF
@@ -3107,7 +3107,7 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
VERSION_INFO="2:48:0"
VERSION_INFO="2:47:0"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
@@ -15393,10 +15393,203 @@ _ACEOF
### Check LLint format
if test x"$ac_cv_sizeof_long" = x"8"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking long printf format" >&5
$as_echo_n "checking long printf format... " >&6; }
if test "$cross_compiling" = yes; then :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run test program while cross compiling
See \`config.log' for more details" "$LINENO" 5; }
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
main() { long int c = -1, d = -1; char* f = "%ld"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
$as_echo "found" >&6; }
$as_echo "#define LLINT_FORMAT \"%ld\"" >>confdefs.h
$as_echo "#define LLINT_TYPE long int" >>confdefs.h
else
if test "$cross_compiling" = yes; then :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run test program while cross compiling
See \`config.log' for more details" "$LINENO" 5; }
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
main() { long int c = -1, d = -1; char* f = "%d"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
$as_echo "found" >&6; }
$as_echo "#define LLINT_FORMAT \"%d\"" >>confdefs.h
$as_echo "#define LLINT_TYPE long int" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming not on target machine" >&5
$as_echo "assuming not on target machine" >&6; }
$as_echo "#define LLINT_FORMAT \"%d\"" >>confdefs.h
$as_echo "#define LLINT_TYPE int" >>confdefs.h
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
elif test x"$ac_cv_sizeof_long_long" = x"8"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking long long printf format" >&5
$as_echo_n "checking long long printf format... " >&6; }
if test "$cross_compiling" = yes; then :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run test program while cross compiling
See \`config.log' for more details" "$LINENO" 5; }
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
main() { long long int c = -1, d = -1; char* f = "%lld"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
$as_echo "found" >&6; }
$as_echo "#define LLINT_FORMAT \"%lld\"" >>confdefs.h
$as_echo "#define LLINT_TYPE long long int" >>confdefs.h
else
if test "$cross_compiling" = yes; then :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run test program while cross compiling
See \`config.log' for more details" "$LINENO" 5; }
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
main() { long long int c = -1, d = -1; char* f = "%ld"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
$as_echo "found" >&6; }
$as_echo "#define LLINT_FORMAT \"%ld\"" >>confdefs.h
$as_echo "#define LLINT_TYPE long long int" >>confdefs.h
else
if test "$cross_compiling" = yes; then :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run test program while cross compiling
See \`config.log' for more details" "$LINENO" 5; }
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
main() { long long int c = -1, d = -1; char* f = "%d"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
$as_echo "found" >&6; }
$as_echo "#define LLINT_FORMAT \"%d\"" >>confdefs.h
$as_echo "#define LLINT_TYPE long long int" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming not on target machine" >&5
$as_echo "assuming not on target machine" >&6; }
$as_echo "#define LLINT_FORMAT \"%d\"" >>confdefs.h
$as_echo "#define LLINT_TYPE int" >>confdefs.h
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
else
$as_echo "#define LLINT_FORMAT \"%d\"" >>confdefs.h
$as_echo "#define LLINT_TYPE int" >>confdefs.h
fi
### check for in_addr_t
ac_fn_c_check_type "$LINENO" "in_addr_t" "ac_cv_type_in_addr_t" "#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
"
if test "x$ac_cv_type_in_addr_t" = xyes; then :
@@ -15420,24 +15613,26 @@ if test "${with_zlib+set}" = set; then :
withval=$with_zlib; if test "$withval" != no ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
ZLIB_HOME="$withval"
if test -d "$withval"
then
ZLIB_HOME="$withval"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Sorry, $withval does not exist, checking usual places" >&5
$as_echo "$as_me: WARNING: Sorry, $withval does not exist, checking usual places" >&2;}
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
else
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
ZLIB_HOME=/usr/local
if test ! -f "${ZLIB_HOME}/include/zlib.h"
then
ZLIB_HOME=/usr
fi
fi
#
# Locate zlib, if wanted
#
@@ -16892,7 +17087,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.3, which was
This file was extended by httrack $as_me 3.47.27, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -16959,7 +17154,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.3
httrack config.status 3.47.27
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@@ -1,9 +1,9 @@
AC_INIT([httrack], [3.48.3], [roche+packaging@httrack.com], [httrack], [http://www.httrack.com/])
AC_INIT([httrack], [3.47.27], [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)
AM_INIT_AUTOMAKE
VERSION_INFO="2:48:0"
VERSION_INFO="2:47:0"
AM_MAINTAINER_MODE
AC_PREREQ(2.50)
@@ -39,13 +39,83 @@ AC_SUBST(VERSION_INFO)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
### Check LLint format
if test x"$ac_cv_sizeof_long" = x"8"; then
AC_MSG_CHECKING(long printf format)
AC_TRY_RUN([#include <stdio.h>
main() { long int c = -1, d = -1; char* f = "%ld"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
],
[AC_MSG_RESULT(found)
AC_DEFINE(LLINT_FORMAT,"%ld",[LLint format])
AC_DEFINE(LLINT_TYPE,long int,[LLint type])
],
[
AC_TRY_RUN([#include <stdio.h>
main() { long int c = -1, d = -1; char* f = "%d"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
],
[
AC_MSG_RESULT(found)
AC_DEFINE(LLINT_FORMAT,"%d",[LLint format])
AC_DEFINE(LLINT_TYPE,long int,[LLint type])
],
[
AC_MSG_RESULT(no)
AC_MSG_RESULT(assuming not on target machine)
AC_DEFINE(LLINT_FORMAT,"%d",[LLint format])
AC_DEFINE(LLINT_TYPE,int,[LLint type])
])
])
elif test x"$ac_cv_sizeof_long_long" = x"8"; then
AC_MSG_CHECKING(long long printf format)
AC_TRY_RUN([#include <stdio.h>
main() { long long int c = -1, d = -1; char* f = "%lld"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
],
[AC_MSG_RESULT(found)
AC_DEFINE(LLINT_FORMAT,"%lld",[LLint format])
AC_DEFINE(LLINT_TYPE,long long int,[LLint type])
],
[
AC_TRY_RUN([#include <stdio.h>
main() { long long int c = -1, d = -1; char* f = "%ld"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
],
[
AC_MSG_RESULT(found)
AC_DEFINE(LLINT_FORMAT,"%ld",[LLint format])
AC_DEFINE(LLINT_TYPE,long long int,[LLint type])
],
[
AC_TRY_RUN([#include <stdio.h>
main() { long long int c = -1, d = -1; char* f = "%d"; sscanf("1234", f, &c, &d);
exit (c != 1234 || d != -1); }
],
[
AC_MSG_RESULT(found)
AC_DEFINE(LLINT_FORMAT,"%d",[LLint format])
AC_DEFINE(LLINT_TYPE,long long int,[LLint type])
],
[
AC_MSG_RESULT(no)
AC_MSG_RESULT(assuming not on target machine)
AC_DEFINE(LLINT_FORMAT,"%d",[LLint format])
AC_DEFINE(LLINT_TYPE,int,[LLint type])
])
])
])
else
AC_DEFINE(LLINT_FORMAT,"%d",[LLint format])
AC_DEFINE(LLINT_TYPE,int,[LLint type])
fi
### check for in_addr_t
AC_CHECK_TYPE(in_addr_t,
AC_DEFINE(HTS_DO_NOT_REDEFINE_in_addr_t,,[Check for in_addr_t]),
AC_MSG_WARN([*** in_addr_t not found]),
[#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>])
#include <netinet/in.h>])
### zlib
CHECK_ZLIB()

26
debian/changelog vendored
View File

@@ -1,29 +1,3 @@
httrack (3.48.3-1) unstable; urgency=low
* Updated to 3.48.3 (3.48-3)
-- Xavier Roche <xavier@debian.org> Fri, 11 Apr 2014 20:31:21 +0200
httrack (3.48.2-1) unstable; urgency=low
* Updated to 3.48.2 (3.48-2)
-- Xavier Roche <xavier@debian.org> Thu, 10 Apr 2014 18:30:08 +0200
httrack (3.48.1-1) unstable; urgency=low
* Updated to 3.48.1 (3.48-1)
-- Xavier Roche <xavier@debian.org> Wed, 09 Apr 2014 21:02:08 +0200
httrack (3.47.27-3) unstable; urgency=low
* Do not depend on automake1.9 but on automake instead
see: http://lists.debian.org/debian-devel/2013/05/msg01459.html
closes:#724390
-- Xavier Roche <xavier@debian.org> Thu, 26 Sep 2013 20:09:12 +0200
httrack (3.47.27-1) unstable; urgency=low
* Updated to 3.47.27 (3.47-27)

View File

@@ -1,5 +1,5 @@
usr/lib/libhttrack.so.2.0.48
usr/lib/libhttrack.so.2.0.47
usr/lib/libhttrack.so.2
usr/lib/libhtsjava.so.2.0.48
usr/lib/libhtsjava.so.2.0.47
usr/lib/libhtsjava.so.2
usr/share/httrack/templates

5
debian/rules vendored
View File

@@ -23,11 +23,6 @@ ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
# as suggested by Simon McVittie
# (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=744380)
override_dh_auto_test:
VERBOSE=1 dh_auto_test
configure: configure-stamp
configure-stamp:
dh_testdir

View File

@@ -4,26 +4,7 @@ HTTrack Website Copier release history:
This file lists all changes and fixes that have been made for HTTrack.
3.48-3
+ Fixed: buggy option pannels
+ New: Enforce check against CVE-2014-0160
+ New: improved hashtables to speedup large mirrors
+ New: added unit tests
+ New: Added %a option, allowing to define the "Accept:" header line.
+ New: Added %X option, to define additional request header lines.
+ New: Added option '-%t', preserving the original file type (which may produce non-browseable file locally)
+ Fixed: remove scope id (% character) in dotted address resolution (especially for catchurl proxy)
+ Fixed: build fixes, including for Android, non-SSL releases
+ Fixed: buggy keep-alive handling, leading to waste connections
+ Fixed: removed chroot and setuid features (this is definitely not our business)
+ Fixed: removed MMS (Microsoft Media Server) ripping code (mmsrip) (dead protocol, unmaintained code, licensing issues)
+ Fixed: type mishandling when processing a redirect (such as a .PDF redirecting to another .PDF, with a text/html type tagged in the redirect message)
+ Fixed: infinite loop when attempting to download a file:/// directory on Unix (gp)<br/>
+ Fixed: removed background DNS resolution, prone to bugs
+ Fixed: do not choke on Windows 2000 because of missing SetDllDirectory() (Andy Hewitt)
+ Fixed: %h custom build structure parameter not taken in account (William Clark)
3.47-27
3.47-24
+ New: support for IDNA / RFC 3492 (punycode) handling
+ New: openssl is no longer dynamically probed at stratup, but dynamically linked
+ Fixed: random closing of files/sockets, leading to "zip_zipWriteInFileInZip_failed" assertion, "bogus state" messages, or random garbage in downloaded files

View File

@@ -430,8 +430,6 @@ LANG_I6
Create a Start Page
LANG_I6b
Create a word database of all html pages
LANG_I6c
Build a complete RFC822 mail (MHT/EML) archive of the mirror
LANG_I7
Create error logging and report files
LANG_I8
@@ -480,12 +478,6 @@ LANG_I23
Browser identity
LANG_I23b
Comment to be placed in each HTML file
LANG_I23c
Languages accepted by the browser
LANG_I23d
Additional HTTP headers to be sent in each requests
LANG_I23e
HTTP referer to be sent for initial URLs
LANG_I24
Back to starting page
LANG_I25
@@ -546,8 +538,6 @@ LANG_I35
Make an index
LANG_I35b
Make a word database
LANG_I35c
Build a mail archive
LANG_I36
Log files
LANG_I37
@@ -576,12 +566,6 @@ LANG_I43
Identity
LANG_I43b
HTML footer
LANG_I43c
Languages
LANG_I43d
Additional HTTP Headers
LANG_I43e
Default referer URL
LANG_I44
N# connections
LANG_I45

View File

@@ -1,9 +1,8 @@
bg:27
es:3
cs:21
zh_tw:14
zh:13
hr:29
cz:21
ct:14
cs:13
da:15
de:4
et:16
@@ -12,13 +11,13 @@ fi:28
fr:2
el:26
it:9
ja:19
jp:19
mk:18
hu:11
nl:5
no:23
pl:6
pt_br:12
pt:12
pt:7
ro:25
ru:8
@@ -26,4 +25,4 @@ sk:20
si:24
sv:17
tr:10
uk:22
ua:22

View File

@@ -3,7 +3,7 @@ LANGUAGE_NAME
LANGUAGE_FILE
Cesky
LANGUAGE_ISO
cs
cz
LANGUAGE_AUTHOR
Antonín Matìjèík (matejcik@volny.cz) \r \n
LANGUAGE_CHARSET

View File

@@ -3,7 +3,7 @@ Chinese-BIG5
LANGUAGE_FILE
Chinese-BIG5
LANGUAGE_ISO
zh_TW
ct
LANGUAGE_AUTHOR
David Hing Cheong Hung (DAVEHUNG@mtr.com.hk)\r\n
LANGUAGE_CHARSET

View File

@@ -3,7 +3,7 @@ Chinese-Simplified
LANGUAGE_FILE
Chinese-Simplified
LANGUAGE_ISO
zh
cs
LANGUAGE_AUTHOR
Brook Qin (brookqwr at sina.com) \r\n
LANGUAGE_CHARSET

View File

@@ -1,932 +0,0 @@
LANGUAGE_NAME
Hrvatski
LANGUAGE_FILE
Croatian
LANGUAGE_ISO
hr
LANGUAGE_AUTHOR
Dominko Aždajiæ (domazd@mail.ru) \r\n
LANGUAGE_CHARSET
ISO-8859-2
LANGUAGE_WINDOWSID
Croatian
OK
U redu
Cancel
Odustati
Exit
Svršetak
Close
Zatvoriti
Cancel changes
Opozvati izmjene
Click to confirm
Preuzeti izmjene
Click to get help!
Kliknuti za pomoæ!
Click to return to previous screen
Kliknuti za povratak na prethodni prikaz
Click to go to next screen
Kliknuti za povratak na slijedeæi prikaz
Hide password
Sakriti lozinku
Save project
Pohraniti projekt
Close current project?
Zatvoriti tekuæi projekt?
Delete this project?
Izbrisati taj projekt?
Delete empty project %s?
Izbrisati prazni projekt %s?
Action not yet implemented
Funkcija još nije raspoloživa
Error deleting this project
Pogreška tijekom brisanja tog projekta
Select a rule for the filter
Izaberite neko pravilo za taj filtar
Enter keywords for the filter
Unesite kljuène rijeèi za taj filtar
Cancel
Odustati
Add this rule
Dodati to pravilo
Please enter one or several keyword(s) for the rule
Unesite molim jednu ili više kljuènih rijeèi za to pravilo
Add Scan Rule
Dodati pravilo filtriranja
Criterion
Pravilo filtra:
String
Unesite rijeè:
Add
Dodati
Scan Rules
Pravila filtriranja
Use wildcards to exclude or include URLs or links.\nYou can put several scan strings on the same line.\nUse spaces as separators.\n\nExample: +*.zip -www.*.com -www.*.edu/cgi-bin/*.cgi
Koristite višeznaènik za ukljuèivanje ili iskljuèivanje mrežnih adresa ili poveznica.\nU isti redak možete staviti i nekoliko filtarskih pravila uzastopno.\nUpotrijebite praznine kao razdjelnike.\n\nPrimjerice: +*.zip -www.*.com -www.*.edu/cgi-bin/*.cgi
Exclude links
Izuzete poveznice
Include link(s)
Obuhvaæene poveznice
Tip: To have ALL GIF files included, use something like +www.someweb.com/*.gif. \n(+*.gif / -*.gif will include/exclude ALL GIFs from ALL sites)
Preporuka: Za obuhvaæanje SVIH datoteka GIF, upotrijebite nešto poput +www.neka-mreža.com/*.gif. \n(+*.gif / -*.gif æe ukljuèivat/iskljuèivati SVE GIF-ove sa SVIH stranica)
Save prefs
Pohraniti postavke
Matching links will be excluded:
Shodne poveznice æe biti izuzete:
Matching links will be included:
Shodne poveznice æe biti obuhvaæene:
Example:
Primjer:
gif\r\nWill match all GIF files
gif\r\nPronalazi sve datoteke GIF
blue\r\nWill find all files with a matching 'blue' sub-string such as 'bluesky-small.jpeg'
blue\r\nPronalazi sve datoteke koje sadržavaju 'blue' kao primjerice 'bluesky-small.jpeg'
bigfile.mov\r\nWill match the file 'bigfile.mov', but not 'bigfile2.mov'
bigfile.mov\r\Pronalazi sve datoteke 'bigfile.mov', ali ne i 'bigfile2.mov'
cgi\r\nWill find links with folder name matching sub-string 'cgi' such as /cgi-bin/somecgi.cgi
cgi\r\nPronalazi sve poveznice s mapama koje u nazivu sadrže 'cgi' kao primjerice /cgi-bin/somecgi.cgi
cgi-bin\r\nWill find links with folder name matching whole 'cgi-bin' string (but not cgi-bin-2, for example)
cgi-bin\r\nPronalazi poveznice prema mapama koje u nazivu sadrže cijeli niz 'cgi-bin' (ali ne i primjerice cgi-bin-2)
someweb.com\r\nWill find links with matching sub-string such as www.someweb.com, private.someweb.com etc.
someweb.com\r\nPronalazi poveznice s pod-nizovima poput www.neka-mreža.com, privatno.neka-mreža.com itd.
someweb\r\nWill find links with matching folder sub-string such as www.someweb.com, www.someweb.edu, private.someweb.otherweb.com etc.
someweb\r\nPronalazi poveznice sa shodnim pod-nizom poput www.neka-mreža.com, www.neka-mreža.edu, private.neka-mreža.druga-mreža.com itd.
www.someweb.com\r\nWill find links matching whole 'www.someweb.com' sub-string (but not links such as private.someweb.com/..)
www.someweb.com\r\nPronalazi poveznice koje u nazivu sadrže cijeli pod-niz 'www.neka-mreža.com' (ali ne i poveznice poput privatno.neka-mreža.com/..)
someweb\r\nWill find any links with matching sub-string such as www.someweb.com/.., www.test.abc/fromsomeweb/index.html, www.test.abc/test/someweb.html etc.
someweb\r\nPronalazi bilo koju poveznicu sa shodnim pod-nizom poput www.neka-mreža.com/.., www.primjer.abc/s-neke-mreže/kazalo.html, www.primjer.abc/primjer/neka-mreža.html itd.
www.test.com/test/someweb.html\r\nWill only find the 'www.test.com/test/someweb.html' file. Note that you have to type the complete path (URL + site path)
www.test.com/test/someweb.html\r\nPronalazi samo datoteku 'www.primjer.com/primjer/neka-mreža.html'. Imajte na umu da morate unijeti potpunu putanju (URL + putanja do mrežnog mjesta)
All links will match
Obuhvaæene su sve poveznice
Add exclusion filter
Pridodati filtar izuzimanja
Add inclusion filter
Pridodati filtar obuhvaæanja
Existing filters
Postojeæi filtri
Cancel changes
Opozvati izmjene
Save current preferences as default values
Tekuæe postavke pohraniti kao polazne vrijednosti
Click to confirm
Kliknite za potvrðivanje
No log files in %s!
U %s nema datoteka zapisnika!
No 'index.html' file in %s!
U %s nema datoteke 'index.html'!
Click to quit WinHTTrack Website Copier
Kliknite za okonèavanje rada s WinHTTrack Website Copierom
View log files
Prikazati zapisnièke datoteke
Browse HTML start page
Prikazati poèetnu stranicu HTML-a
End of mirror
Zrcaljenje sadržaja je završeno
View log files
Prikazati zapisnièke datoteke
Browse Mirrored Website
Prikazati zrcaljene sadržaje
New project...
Novi projekt...
View error and warning reports
Prikazati izvješæa o pogreškama i upozorenjima
View report
Prikaz izvješæa
Close the log file window
Zatvoriti okno zapisnièke datoteke
Info type:
Vrsta informacija:
Errors
Pogreške
Infos
Informacije
Find
Pronaæi
Find a word
Pronaæi rijeè
Info log file
Zapisnièka info-datoteka
Warning/Errors log file
Datoteka zapisa o upozorenjima/pogreškama
Unable to initialize the OLE system
Sustav OLE-a nije mogao biti pokrenut
WinHTTrack could not find any interrupted download file cache in the specified folder!
WinHTTrack u navedenoj mapi nije mogao pronaæi meðupohranu nikakvog prekinutog preuzimanja datoteka!
Could not connect to provider
Povezivanje s dobavljaèem nije uspjelo
receive
zaprimiti
request
zatražiti
connect
povezati
search
tražiti
ready
gotovo
error
pogreška
Receiving files..
Zaprimanje datoteka..
Parsing HTML file..
Rašèlanjivanje datoteke HTML-a..
Purging files..
Èišæenje datoteka..
Loading cache in progress..
U tijeku je uèitavanje meðuspremnika..
Parsing HTML file (testing links)..
Rašèlanjivanje datoteke HTML-a (provjeravanje poveznica)..
Pause - Toggle [Mirror]/[Pause download] to resume operation
Stanka - Nastavak putem izbornièkih naredbi [Zrcaljenje]/[Stanka preuzimanja]
Finishing pending transfers - Select [Cancel] to stop now!
Završavaju se tekuæi prijenosi - Trenutna obustava pomoæu [Odustati]
scanning
pregledavanje
Waiting for scheduled time..
Èeka se zadano vrijeme..
Transferring data..
Prenošenje podataka..
Connecting to provider
Povezivanje s dobavljaèem
[%d seconds] to go before start of operation
[%d sekundi] do poèetka radnje
Site mirroring in progress [%s, %s bytes]
Zrcaljenje sadržaja je u tijeku [%s, %s bajta]
Site mirroring finished!
Zrcaljenje sadržaja je završeno!
A problem occured during the mirroring operation\n
Tijekom zrcaljenja je nastao jedan problem\n
\nDuring:\n
\nTrajanje:\n
\nSee the log file if necessary.\n\nClick FINISH to quit WinHTTrack Website Copier.\n\nThanks for using WinHTTrack!
\nPojedinosti po potrebi pogledajte u zapisnièkoj datoteci.\n\nKliknite na ZAVRŠITI za okonèavanje rada WinHTTrack Website Copiera.\n\nHvala Vam na uporabi WinHTTracka!
Mirroring operation complete.\nClick Exit to quit WinHTTrack.\nSee log file(s) if necessary to ensure that everything is OK.\n\nThanks for using WinHTTrack!
Zrcaljenje je dovršeno.\nKliknite na Svršetak za okonèavanje rada s WinHTTrackom.\nPogledajte po potrebi u zapisnik(e) kako bi se uvjerili da je sve u redu.\n\nHvala Vam na uporabi WinHTTracka!!
* * MIRROR ABORTED! * *\r\nThe current temporary cache is required for any update operation and only contains data downloaded during the present aborted session.\r\nThe former cache might contain more complete information; if you do not want to lose that information, you have to restore it and delete the current cache.\r\n[Note: This can easily be done here by erasing the hts-cache/new.* files]\r\n\r\nDo you think the former cache might contain more complete information, and do you want to restore it?
* * ZRCALJENJE JE PREKINUTO! * *\r\nTekuæi privremeni meðuspremnik æe biti potreban za neku buduæu aktualizaciju i sadrži samo podatke, koji su preuzeti tijekom upravo prekinutog zasjedanja.\r\nPrethodni meðuspremnik možda sadrži potpunije podatke; ukoliko te podatke ne želite izgubiti, morate ih ponovno uspostaviti i izbrisati tekuæi meðuspremnik.\r\n[Napomena: To se jednostavno može napraviti brisanjem datoteka hts-cache/new.*]\r\n\r\nMislite li da ovom zasjedanju prethodeæi meðuspremnik može sadržavati potpunije podatke, i želite li ga ponovno uspostaviti?
* * MIRROR ERROR! * *\r\nHTTrack has detected that the current mirror is empty. If it was an update, the previous mirror has been restored.\r\nReason: the first page(s) either could not be found, or a connection problem occured.\r\n=> Ensure that the website still exists, and/or check your proxy settings! <=
* * POGREŠKA PRI ZRCALJENJU! * *\r\nHTTrack je zapazio da je tekuæe zrcalo prazno. Ukoliko je to bila neka dogradnja, onda je prethodno zrcalo ponovno uspostavljeno.\r\nRazlog: ili prva stranica nije mogla biti pronaðena, ili se pak pojavio neki problem.\r\n=> Uvjerite se da dotièno mrežno mjesto još uvijek postoji, i/ili provjerite postavke Vašeg usmjerivaèa! <=
\n\nTip: Click [View log file] to see warning or error messages
\n\nPreporuka: Kliknite na [Prikazati zapisnièke datoteke], kako bi vidjeli upozorenja ili dojave pogreški
Error deleting a hts-cache/new.* file, please do it manually
Pogreška pri brisanju datoteke hts-cache/new.*, molim obavite to ruèno
Do you really want to quit WinHTTrack Website Copier?
Doista želite okonèati rad s WinHTTrack Website Copierom?
- Mirroring Mode -\n\nEnter address(es) in URL box
- Stanje zrcaljenja -\n\nUnesite adresu(-e) u polje URL-a
- Interactive Wizard Mode (questions) -\n\nEnter address(es) in URL box
- Interaktivno stanje vodièa s povratnim pitanjima -\n\nUnesite adresu(-e) u polje URL-a
- File Download Mode -\n\nEnter file address(es) in URL box
- Stanje preuzimanja datoteka -\n\nUnesite adresu(-e) datoteke u polje URL-a
- Link Testing Mode -\n\nEnter Web address(es) with links to test in URL box
- Stanje provjere poveznica -\n\nUnesite spletnu adresu(-e) s poveznicama za provjeravanje u polje URL-a
- Update Mode -\n\nVerify address(es) in URL box, check parameters if necessary then click on 'NEXT' button
- Stanje nadograðivanja -\n\nOvjerite adresu(-e) u polje URL-a, provjerite po potrebi parametre a zatim kliknite na gumb 'SLIJEDEÆE'
- Resume Mode (Interrupted Operation) -\n\nVerify address(es) in URL box, check parameters if necessary then click on 'NEXT' button
- Stanje nadovezivanja (prekinute radnje) -\n\nOvjerite adresu(-e) u polje URL-a, provjerite po potrebi parametre a zatim kliknite na gumb 'SLIJEDEÆE'
Log files Path
Putanja zapisnièkih datoteka
Path
Putanja
- Links List Mode -\n\nUse URL box to enter address(es) of page(s) containing links to mirror
- Stanje nabrajanja poveznica -\n\nKoristite okvir URL-a za unos adrese(-a) stranice(-a) koje sadrže dotiène poveznice
New project / Import?
Novi projekat / Uvoz?
Choose criterion
Odaberite kriterij
Maximum link scanning depth
Maksimum dubine grananja poveznica
Enter address(es) here
Ovdje unijeti adresu(-e)
Define additional filtering rules
Odrediti dodatna pravila filtriranja
Proxy Name (if needed)
Naziv posrednièkog raèunalo (po potrebi)
Proxy Port
Posrednièki port
Define proxy settings
Odredite postavke posrednika
Use standard HTTP proxy as FTP proxy
Koristiti standardni posrednik HTTP-a kao posrednik FTP-a
Path
Putanja
Select Path
Odabrati putanju
Path
Putanja
Select Path
Odabrati putanju
Quit WinHTTrack Website Copier
Okonèati rad WinHTTrack Website Copiera
About WinHTTrack
O programu WinHTTrack
Save current preferences as default values
Tekuæe postavke pohraniti kao polazne vrijednosti
Click to continue
Kliknite ovdje za nastavak
Click to define options
Kliknite ovdje za odreðivanje moguænosti
Click to add a URL
Kliknite ovdje za dodavanje URL-a
Load URL(s) from text file
URL(-e) uèitati iz tekstualne datoteke
WinHTTrack preferences (*.opt)|*.opt||
Postavke WinHTTracka (*.opt)|*.opt||
Address List text file (*.txt)|*.txt||
Tekstualna datoteka sa spiskom adresa (*.txt)|*.txt||
File not found!
Datoteka nije pronaðena!
Do you really want to change the project name/path?
Doista želite izmijeniti naziv i putanju projekta?
Load user-default options?
Uèitati korisnikom zadane polazne moguænosti?
Save user-default options?
Pohraniti korisnikom zadane polazne moguænosti?
Reset all default options?
Sve moguænosti vratiti na polazno?
Welcome to WinHTTrack!
Dobrodošli u WinHTTrack!
Action:
Radnja:
Max Depth
Maksimum dubine
Maximum external depth:
Maksimum vanjske dubine:
Filters (refuse/accept links) :
Filtri (odbiti/pohraniti poveznice) :
Paths
Putanje
Save prefs
Postavke pohraniti
Define..
Odrediti..
Set options..
Postaviti moguænosti..
Preferences and mirror options:
Postavke i moguænosti zrcaljenja:
Project name
Naziv projekta
Add a URL...
Dodati mrežnu adresu...
Web Addresses: (URL)
Mrežne adrese: (URL)
Stop WinHTTrack?
Zaustaviti WinHTTrack?
No log files in %s!
U %s nema zapisnièkih datoteka!
Pause Download?
Napraviti stanku preuzimanja?
Stop the mirroring operation
Zaustaviti postupak zrcaljenja
Minimize to System Tray
Minimizirati u sustavnu traku odlaganja
Click to skip a link or stop parsing
Kliknite za preskok poveznice ili zaustavljanje rašèlanjivanja
Click to skip a link
Kliknite za preskok poveznice
Bytes saved
Pohranjeno bajta
Links scanned
Obraðene poveznice
Time:
Vrijeme:
Connections:
Veze:
Running:
Djelatno:
Hide
Sakriti
Transfer rate
Stopa prijenosa
SKIP
PRESKOÈITI
Information
Informacija
Files written:
Zapisano datoteka:
Files updated:
Aktualizirano datoteka:
Errors:
Pogreške:
In progress:
U tijeku:
Follow external links
Slijediti vanjske poveznice
Test all links in pages
Na stranicama provjeriti sve poveznice
Try to ferret out all links
Pokušati slijediti sve poveznice
Download HTML files first (faster)
Najprije preuzimati datoteke HTML-a (brže)
Choose local site structure
Odaberite mjesnu strukturu sadržaja
Set user-defined structure on disk
Sâmi odredite strukturu na disku
Use a cache for updates and retries
Za dogradnje i ponavljanja koristiti meðuspremnik
Do not update zero size or user-erased files
Ne nadopunjavati datoteke koje su prazne ili one koje je korisnik izbrisao
Create a Start Page
Napraviti poèetnu stranicu
Create a word database of all html pages
Napraviti spisak rijeèi sa svih stranica HTML-a
Create error logging and report files
Napraviti datoteke zapisnika pogrešaka i izvješæa o tijeku postupka
Generate DOS 8-3 filenames ONLY
Generirati nazive datoteka SAMO sukladno DOS-u 8-3
Generate ISO9660 filenames ONLY for CDROM medias
Generirati nazive datoteka SAMO sukladno ISO9660 za medije CDROM-a
Do not create HTML error pages
Ne stvarati stranice pogrešaka HTML-a
Select file types to be saved to disk
Odaberite vrste datoteka, koje treba pohranjivati na disku
Select parsing direction
Odaberite smjer rašèlanjivanja
Select global parsing direction
Odaberite opæi smjer rašèlanjivanja
Setup URL rewriting rules for internal links (downloaded ones) and external links (not downloaded ones)
Postavke pravila prilagoðavanja URL-a za unutarnje (jednom veæ preuzimane) i vanjske (ni jednom nisu preuzimane) poveznice
Max simultaneous connections
Maksimum istovremenih prikljuèivanja/veza
File timeout
Vrijeme èekanja na datoteke
Cancel all links from host if timeout occurs
Pri prekoraèenju vremena èekanja prekinuti sve poveznice prema dotiènom raèunalu
Minimum admissible transfer rate
Najniža podnošljiva stopa prijenosa
Cancel all links from host if too slow
Prekinuti sve poveznice prema ugostiteljskom raèunalu ako je presporo
Maximum number of retries on non-fatal errors
Najviši broj pokušaja ponavljanja pri ne-fatalnim pogreškama
Maximum size for any single HTML file
Vrhunac velièine neke pojedinaène datoteke HTML-a
Maximum size for any single non-HTML file
Vrhunac velièine neke pojedinaène datoteke ne-HTML-a
Maximum amount of bytes to retrieve from the Web
Vrhunac iznosa u bajtima za dobaviti s mrežnih mjesta
Make a pause after downloading this amount of bytes
Napraviti stanku nakon preuzimanja tog iznosa u bajtima
Maximum duration time for the mirroring operation
Vrhunac vremena trajanja za postupak zrcaljenja
Maximum transfer rate
Vrhunac stope prijenosa
Maximum connections/seconds (avoid server overload)
Najviši broj veza/sekundi (sprjeèava preoptereæivanje poslužitelja)
Maximum number of links that can be tested (not saved!)
Najviši broj poveznica, koje mogu biti provjeravane (za pohranjivanje nema ogranièenja!)
Browser identity
Preglednièko obilježje
Comment to be placed in each HTML file
Komentar koji æe biti smješten u svakoj datoteci HTML-a
Back to starting page
Natrag na poèetnu stranicu
Save current preferences as default values
Tekuæe postavke pohraniti kao polazne vrijednosti
Click to continue
Kliknite za nastavak
Click to cancel changes
Kliknuti za opoziv izmjena
Follow local robots rules on sites
Na mrežnim mjestima slijediti pravila mjesnih robota
Links to non-localised external pages will produce error pages
Poveznice prema nepreslikanim vanjskim stranicama æe stvarati stranice pogreški
Do not erase obsolete files after update
Nakon dogradnje ne brisati zastarjele datoteke
Accept cookies?
Prihvatiti kolaèiæ?
Check document type when unknown?
Provjeravati vrstu datoteke ukoliko je nepoznata?
Parse java applets to retrieve included files that must be downloaded?
Rašèlanjivati java applete radi pronalaženja obuhvaæenih datoteka, koje još moraju biti preuzete?
Store all files in cache instead of HTML only
Spremati sve datoteke u meðuspremnik a ne samo one u HTML-u
Log file type (if generated)
Vrsta datoteke zapisnika (ukoliko je naèinjen)
Maximum mirroring depth from root address
Najveæa dubina zrcaljenja od prve adrese
Maximum mirroring depth for external/forbidden addresses (0, that is, none, is the default)
Najveæa dubina zrcaljenja za vanjske/zabranjene adrese (polazno je 0, tj. bez vanjskog preuzimanja)
Create a debugging file
Naèiniti datoteku za traženje pogrešaka
Use non-standard requests to get round some server bugs
Koristiti nestandardne zahtjeve, kako bi se zaobišle neke poslužiteljske pogreške
Use old HTTP/1.0 requests (limits engine power!)
Koristiti zahtjeve starog HTTP/1.0 (ogranièava brzinu rada!)
Attempt to limit retransfers through several tricks (file size test..)
Raznim varkama pokušati ogranièiti opetovanja prijenosa (provjera velièine datoteka..)
Attempt to limit the number of links by skipping similar URLs (www.foo.com==foo.com, http=https ..)
Preskakanjem sliènih URL-a (www.foo.com==foo.com, http=https ..) pokušati ogranièiti broj poveznica
Write external links without login/password
Vanjske poveznice zapisivati bez prijave/lozinke
Write internal links without query string
Unutarnje poveznice zapisivati bez teksta za upite
Get non-HTML files related to a link, eg external .ZIP or pictures
Dobavljati datoteke ne-HTML-a, združene s poveznicom (primjerice vanjski .ZIP ili slike)
Test all links (even forbidden ones)
Provjeravati sve poveznice (èak i one zabranjene)
Try to catch all URLs (even in unknown tags/code)
Pokušati pronaæi sve URL-e (èak i u nepoznatim oznakama/skriptama)
Get HTML files first!
Dobaviti najprije datoteke HTML-a!
Structure type (how links are saved)
Vrsta strukture (kako se pohranjuju poveznice)
Use a cache for updates
Za dogradnje koristiti meðuspremnik
Do not re-download locally erased files
Ne preuzimati ponovno datoteke, koje su veæ mjesno izbrisane
Make an index
Napraviti kazalo
Make a word database
Napraviti spisak rijeèi
Log files
Zapisnièke datoteke
DOS names (8+3)
Nazivi sukladno DOS-u (8+3)
ISO9660 names (CDROM)
Nazivi prema ISO9660 (CDROM)
No error pages
Bez stranica pogrešaka
Primary Scan Rule
Glavno pravilo filtra
Travel mode
Naèin traženja
Global travel mode
Globalni naèin traženja
These options should be modified only exceptionally
Ove moguænosti bi trebale biti preinaèavane samo iznimno
Activate Debugging Mode (winhttrack.log)
Aktivirati postupak traženja pogrešaka (winhttrack.log)
Rewrite links: internal / external
Prilagoditi poveznièke adrese: unutarnje / vanjske
Flow control
Nadzor toka
Limits
Granice
Identity
Obilježje
HTML footer
Podnožje HTML-a
N# connections
Broj veza
Abandon host if error
Pri pogreškama napustiti ugostitelja
Minimum transfer rate (B/s)
Minimum stope prijenosa (B/s)
Abandon host if too slow
Napustiti ugostitelja ukoliko je prespor
Configure
Prilagoditi
Use proxy for ftp transfers
Koristiti posrednika za prijenose putem FTP-a
TimeOut(s)
Vremenska ogranièenja
Persistent connections (Keep-Alive)
Održavati veze (Keep-Alive)
Reduce connection time and type lookup time using persistent connections
Održavane veze smanjuju vrijeme povezivanja i vrijeme za traženje vrsta
Retries
Opetovanja
Size limit
Ogranièenje velièine
Max size of any HTML file (B)
Najviši broj bajta u datotekama HTML-a
Max size of any non-HTML file
Najveæa velièina datoteka ne-HTML-a
Max site size
Najveæa velièina sadržaja
Max time
Najduže vrijeme
Save prefs
Pohraniti postavke
Max transfer rate
Vrhunac stope prijenosa
Follow robots.txt
Slijediti robots.txt
No external pages
Bez vanjskih stranica
Do not purge old files
Ne brisati stare datoteke
Accept cookies
Prihvaæati kolaèiæe
Check document type
Provjeravati vrstu dokumenata
Parse java files
Rašèlanjivati datoteke Java
Store ALL files in cache
Spremati SVE datoteke u meðuspremnik
Tolerant requests (for servers)
Snošljivi zahtjevi (za poslužitelje)
Update hack (limit re-transfers)
Iznuda dogradnji (ogranièava opetovane prijenose)
URL hacks (join similar URLs)
URL hacks (združuje sliène URL-e)
Force old HTTP/1.0 requests (no 1.1)
Nametati zahtjeve starog HTTP/1.0 (ne 1.1)
Max connections / seconds
Najviši broj veza / sekundi
Maximum number of links
Najviši broj poveznica
Pause after downloading..
Èekati nakon preuzimanja..
Hide passwords
Sakriti lozinke
Hide query strings
Sakriti tekst za upite
Links
Poveznice
Build
Graða
Experts Only
Samo za struènjake
Flow Control
Nadzor toka
Limits
Ogranièenja
Browser ID
Preglednièki ID
Scan Rules
Pravila filtriranja
Spider
Pauk
Log, Index, Cache
Zapisnik, Kazalo, Meðuspremnik
Proxy
Posrednik
MIME Types
Vrste MIME
Do you really want to quit WinHTTrack Website Copier?
Doista želite okonèati rad WinHTTrack Website Copiera?
Do not connect to a provider (already connected)
Ne povezivati s dobaviteljem (veæ je povezano)
Do not use remote access connection
Ne koristiti vezu daljinskog pristupa
Schedule the mirroring operation
Odrediti vrijeme zrcaljenja
Quit WinHTTrack Website Copier
Okonèati rad WinHTTrack Website Copiera
Back to starting page
Natrag na poèetnu stranicu
Click to start!
Kliknite za poèetak!
No saved password for this connection!
Za tu vezu nema pohranjene lozinke!
Can not get remote connection settings
Ne mogu se dobiti postavke daljinske veze
Select a connection provider
Odaberite dobavitelja veze
Start
Zapoèeti
Please adjust connection parameters if necessary,\nthen press FINISH to launch the mirroring operation.
Po potrebi prilagodite molim parametre veze,\na zatim stisnite ZAVRŠITI kako bi pokrenuli zrcaljenje.
Save settings only, do not launch download now.
Samo pohraniti postavke, preuzimanje ne pokretati sada.
On hold
Na èekanju
Transfer scheduled for: (hh/mm/ss)
Prijenos je predviðen za: (hh/mm/ss)
Start
Zapoèeti
Connect to provider (RAS)
Povezati s dobavljaèem (RAS)
Connect to this provider
Povezati s tim dobavljaèem
Disconnect when finished
Prekinuti vezu kada bude gotovo
Disconnect modem on completion
Po dovršetku odvojiti modemsku vezu
\r\n(Please notify us of any bug or problem)\r\n\r\nDevelopment:\r\nInterface (Windows): Xavier Roche\r\nSpider: Xavier Roche\r\nJavaParserClasses: Yann Philippot\r\n\r\n(C)1998-2003 Xavier Roche and other contributors\r\nMANY THANKS for translation tips to:\r\nRobert Lagadec (rlagadec@yahoo.fr)
\r\n(Molimo da nas obavijestite o svim pogreškama i poteškoæama)\r\n\r\nRazvoj:\r\nSuèelje (Windows): Xavier Roche\r\nPauk: Xavier Roche\r\nRazrediRašèlanjivaèaJave: Yann Philippot\r\n\r\n(C)1998-2003 Xavier Roche i drugi suradnici\r\nPUNO HVALA za prijevodne preporuke upuæujemo:\r\nRobert Lagadec (rlagadec@yahoo.fr)
About WinHTTrack Website Copier
O programu WinHTTrack Website Copier
Please visit our Web page
Molimo da posjetite našu spletnu stranicu
Wizard query
Upit vodièa
Your answer:
Vaš odgovor:
Link detected..
Pronaðena je poveznica..
Choose a rule
Birajte pravilo
Ignore this link
Zanemariti tu poveznicu
Ignore directory
Zanemariti mape
Ignore domain
Zanemariti domenu
Catch this page only
Dobaviti samo tu stranicu
Mirror site
Sadržaj zrcaljenja
Mirror domain
Domena zrcaljenja
Ignore all
Bez poveznica
Wizard query
Upit vodièa
NO
NE
File
Datoteka
Options
Moguænosti
Log
Zapisnik
Window
Okno
Help
Pomoæ
Pause transfer
Napraviti stanku prijenosa
Exit
Svršetak
Modify options
Izmijeniti moguænosti
View log
Prikazati zapisnik
View error log
Prikazati zapisnik pogrešaka
View file transfers
Prikazati prijenose datoteka
Hide
Sakriti
About WinHTTrack Website Copier
O programu WinHTTrack Website Copier
Check program updates...
Potražiti programske dogradnje...
&Toolbar
&Traka alatki
&Status Bar
&Traka stanja
S&plit
Raz&dijeliti
File
Datoteka
Preferences
Postavke
Mirror
Zrcalo
Log
Zapisnik
Window
Okno
Help
Pomoæ
Exit
Svršetak
Load default options
Uèitati polazne moguænosti
Save default options
Pohraniti polazne moguænosti
Reset to default options
Vratiti polazne moguænosti
Load options...
Uèitati moguænosti...
Save options as...
Moguænosti pohraniti kao...
Language preference...
Jeziène postavke...
Contents...
Sadržaji...
About WinHTTrack...
O programu WinHTTrack...
New project\tCtrl+N
Novi projekat\tCtrl+N
&Open...\tCtrl+O
&Otvoriti...\tCtrl+O
&Save\tCtrl+S
&Pohraniti\tCtrl+S
Save &As...
Pohraniti &kao...
&Delete...
&Izbrisati...
&Browse sites...
&Pregledati sadržaje...
User-defined structure
Korisnikom odreðena struktura
%n\tName of file without file type (ex: image)\r\n%N\tName of file including file type (ex: image.gif)\r\n%t\tFile type only (ex: gif)\r\n%p\tPath [without ending /] (ex: /someimages)\r\n%h\tHost name (ex: www.someweb.com)\r\n%M\tMD5 URL (128 bits, 32 ascii bytes)\r\n%Q\tMD5 query string (128 bits, 32 ascii bytes)\r\n%q\tMD5 small query string (16 bits, 4 ascii bytes)\r\n\r\n%s?\tShort name (ex: %sN)
%n\tNaziv datoteke bez nastavka (npr. slika)\r\n%N\tNaziv datoteke s nastavkom (npr. slika.gif)\r\n%t\tSamo nastavak naziva datoteke (npr. gif)\r\n%p\tPutanja [bez svršetka /] (npr. /nekeslike)\r\n%h\tNaziv ugostitelja (npr. www.nekisplet.com)\r\n%M\tMD5 URL (128 bita, 32 ascii bajta)\r\n%Q\tTekst upita MD5 (128 bita, 32 ascii bajta)\r\n%q\tKratki tekst upita MD5 (16 bita, 4 ascii bajta)\r\n\r\n%s?\tKratki naziv (npr. %sN)
Example:\t%h%p/%n%q.%t\n->\t\tc:\\mirror\\www.someweb.com\\someimages\\image.gif
Primjerice:\t%h%p/%n%q.%t\n->\t\tc:\\zrcaljenje\\www.nekisplet.com\\nekeslike\\slika.gif
Proxy settings
Postavke posrednika
Proxy address:
Adresa posrednika:
Proxy port:
Port posrednika:
Authentication (only if needed)
Ovjeravanje (samo po potrebi)
Login
Prijava
Password
Lozinka
Enter proxy address here
Ovdje unesite adresu posrednika
Enter proxy port here
Ovdje unesite port posrednika
Enter proxy login
Unesite prijavu na posredniku
Enter proxy password
Unesite lozinku na posredniku
Enter project name here
Ovdje unesite naziv projekta
Enter saving path here
Ovdje unesite putanju za pohranjivanje
Select existing project to update
Birajte postojeæi projekt za dogradnju
Click here to select path
Ovdje kliknite za izbor putanje
Select or create a new category name, to sort your mirrors in categories
Odaberite ili nadjenite neki naziv novoj kategoriji, kako bi Vaša zrcaljenja svrstali u kategorije
HTTrack Project Wizard...
Pomoènik za projekte HTTracka...
New project name:
Naziv novog projekta:
Existing project name:
Naziv postojeæeg projekta:
Project name:
Naziv projekta:
Base path:
Osnovna putanja:
Project category:
Kategorija projekta:
C:\\My Web Sites
C:\\Moji spletni sadržaji
Type a new project name, \r\nor select existing project to update/resume
Utipkajte naziv novog projekta, \r\nili odaberite postojeæi projekat za dograditi/nadovezati
New project
Novi projekat
Insert URL
Umetnite URL
URL:
URL:
Authentication (only if needed)
Ovjeravanje (samo ako je nužno)
Login
Prijava
Password
Lozinka
Forms or complex links:
Obrasci ili kompleksne poveznice:
Capture URL...
Zahvatiti URL...
Enter URL address(es) here
Ovdje unesite adresu(-e) URL-a
Enter site login
Unesite prijavu za to mrežno mjesto
Enter site password
Unesite lozinku za to mrežno mjesto
Use this capture tool for links that can only be accessed through forms or javascript code
Koristite ovu funkciju za dobavu povezanih sadržaja, kojima se inaèe može pristupiti samo putem obrazaca ili kôda JavaScript
Choose language according to preference
Izaberite jezik
Catch URL!
Dobaviti URL!
Please set temporary browser proxy settings to the following values (Copy/Paste Proxy Address and Port).\nThen click on the Form SUBMIT button in your browser page, or click on the specific link you want to capture.
Molimo da privremeno izmijenite preglednikove postavke posrednièkog poslužitelja na slijedeæe vrijednosti (Adresu i port posrednika odavdje preslikati).\nKliknite zatim na stranici obrasca u Vašem pregledniku na gumb SUBMIT/POSLATI ili pak na odreðenu poveznicu, koju želite dobaviti.
This will send the desired link from your browser to WinHTTrack.
Time æe željena poveznica iz Vašeg preglednika biti poslana u WinHTTrack.
ABORT
PREKINUTI
Copy/Paste the temporary proxy parameters here
Privremene postavke posrednièkog poslužitelja preslikati odavdje
Cancel
Odustati
Unable to find Help files!
Nije bilo moguæe pronaæi datoteke Pomoæi!
Unable to save parameters!
Nije bilo moguæe pohraniti parametre!
Please drag only one folder at a time
Povucite mišom molim samo jednu mapu istovremeno
Please drag only folders, not files
Povucite mišom molim samo mape, ne datoteke
Please drag folders only
Povucite mišom molim samo mape
Select user-defined structure?
Za preslik sadržaja odabrati korisnikom odreðenu strukturu?
Please ensure that the user-defined-string is correct,\notherwise filenames will be bogus!
Provjerite molim je li korisnikom odreðeni znakovni niz ispravan,\nu suprotnom æe nastati iskrivljeni nazivi datoteka!
Do you really want to use a user-defined structure?
Doista želite koristiti korisnikom odreðenu strukturu?
Too manu URLs, cannot handle so many links!!
Previše je URL-a, ne mogu obraðivati toliko poveznica!!
Not enough memory, fatal internal error..
Nema dovoljno spremnika, fatalna unutarnja pogreška..
Unknown operation!
Nepoznata operacija!
Add this URL?\r\n
Dodati taj URL?\r\n
Warning: main process is still not responding, cannot add URL(s)..
Warning: main process is still not responding, cannot add URL(s)..
Type/MIME associations
Type/MIME associations
File types:
Vrste datoteka:
MIME identity:
Istovjetnost MIME:
Select or modify your file type(s) here
Ovdje birajte ili izmijenite Vaše vrste datoteka
Select or modify your MIME type(s) here
Ovdje birajte ili izmijenite Vaše vrste MIME
Go up
Na gore
Go down
Na dolje
File download information
Informacije o preuzimanju datoteka
Freeze Window
Uglaviti okno
More information:
Više informacija:
Welcome to WinHTTrack Website Copier!\n\nPlease click on the NEXT button to\n\n- start a new project\n- or resume a partial download
Dobrodošli u program WinHTTrack Website Copier!\n\nKliknite molim na gumb SLIJEDEÆE kako bi\n\n- zapoèeli novi projekat\n- ili nastavili nedovršeno preuzimanje
File names with extension:\nFile names containing:\nThis file name:\nFolder names containing:\nThis folder name:\nLinks on this domain:\nLinks on domains containing:\nLinks from this host:\nLinks containing:\nThis link:\nALL LINKS
Nazivi datoteka s proširenjem:\nNazivi datoteka sadržavaju:\nTaj naziv datoteke:\nNazivi mapa sadržavaju:\nTaj naziv mape:\nPoveznice u toj domeni:\nPoveznice u domenama sadržavaju:\nPoveznice s tog ugostitelja:\nPoveznice sadržavaju:\nTa poveznica:\nSVE POVEZNICE
Show all\nHide debug\nHide infos\nHide debug and infos
Prikazati sve\nSakriti debug\nSakriti informacije\nSakriti debug i informacije
Site-structure (default)\nHtml in web/, images/other files in web/images/\nHtml in web/html, images/other in web/images\nHtml in web/, images/other in web/\nHtml in web/, images/other in web/xxx, where xxx is the file extension\nHtml in web/html, images/other in web/xxx\nSite-structure, without www.domain.xxx/\nHtml in site_name/, images/other files in site_name/images/\nHtml in site_name/html, images/other in site_name/images\nHtml in site_name/, images/other in site_name/\nHtml in site_name/, images/other in site_name/xxx\nHtml in site_name/html, images/other in site_name/xxx\nAll files in web/, with random names (gadget !)\nAll files in site_name/, with random names (gadget !)\nUser-defined structure..
Struktura sadržaja (polazno)\nHTML u spletu/, slike/ostale datoteke u spletu/slike/\nHTML u spletu/html, slike/ostalo u spletu/slike\nHTML u spletu/, slike/ostalo u spletu/\nHTML u spletu/, slike/ostalo u spletu/xxx, pri èemu je xxx proširenje naziva datoteke\nHTML u spletu/html, slike/ostalo u spletu/xxx\nStruktura sadržaja, bez www.domena.xxx/\nHTML u naziv_sadržaja/, slike/ostale datoteke u nazivu_sadržaja/slike/\nHTML u naziv_sadržaja/html, slike/ostalo u naziv_sadržaja/slike\nHTML u naziv_sadržaja/, slike/ostalo u naziv_sadržaja/\nHTML u naziv_sadržaja/, slike/ostalo u naziv_sadržaja/xxx\nHTML u naziv_sadržaja/html, slike/ostalo u naziv_sadržaja/xxx\nSve datoteke u spletu/, s nasumiènim nazivima (gadget !)\nSve datoteke u naziv_sadržaja/, s nasumiènim nazivima (gadget !)\nKorisnikom odreðena struktura..
Just scan\nStore html files\nStore non html files\nStore all files (default)\nStore html files first
Samo pregledati poveznice\nStpremiti datoteke HTML-a\nStpremiti datoteke ne-HTML-a\nSpremiti sve datoteke (polazno)\nSpremiti najprije datoteke HTML-a
Stay in the same directory\nCan go down (default)\nCan go up\nCan both go up & down
Ostati u istoj mapi\nMože iæi dolje (polazno)\nMože iæi gore\nMože iæi i gore i dolje
Stay on the same address (default)\nStay on the same domain\nStay on the same top level domain\nGo everywhere on the web
Ostati na istoj adresi (polazno)\nOstati u istoj domeni\nOstati u istoj demeni vršne razine\nIæi posvuda po spletu
Never\nIf unknown (except /)\nIf unknown
Nikada\nUkoliko je nepoznato (izuzev /)\nUkoliko je nepoznato
no robots.txt rules\nrobots.txt except wizard\nfollow robots.txt rules
bez pravila iz robots.txt\nslijediti pravila iz robots.txt s izuzetkom pomoènika\nslijediti pravila iz robots.txt
normal\nextended\ndebug
uobièajeno\nprošireno\ndebug
Download web site(s)\nDownload web site(s) + questions\nGet individual files\nDownload all sites in pages (multiple mirror)\nTest links in pages (bookmark test)\n* Continue interrupted download\n* Update existing download
Preuzimanje spletnih sadržaja\nPreuzimanje spletnih sadržaja + pitanja\nDobavljanje pojedinih datoteka\nPreuzimanje svih sadržaja sa stranica (višestruko zrcaljenje)\nProvjeriti poveznice u stranicama (provjera poveznica)\n* Nastaviti prekinuto preuzimanje\n* Aktualizirati postojeæe preuzimanje
Relative URI / Absolute URL (default)\nAbsolute URL / Absolute URL\nAbsolute URI / Absolute URL\nOriginal URL / Original URL
Relativni URI / Apsolutni URL (polazno)\nApsolutni URL / Apsolutni URL\nApsolutni URI / Apsolutni URL\nIzvorni URL / Izvorni URL
Open Source offline browser
Open Source offline browser
Website Copier/Offline Browser. Copy remote websites to your computer. Free.
Preslikavatelj spletnih sadržaja/Preglednik mjesnih sadržaja. Preslikavanje internetskih sadržaja na Vaše raèunalo. Besplatno.
httrack, winhttrack, webhttrack, offline browser
httrack, winhttrack, webhttrack, offline browser
URL list (.txt)
Spisak URL-a (.txt)
Previous
Prethodno
Next
Slijedeæe
URLs
URL-i
Warning
Upozorenje
Your browser does not currently support javascript. For better results, please use a javascript-aware browser.
Vaš preglednik trenutno ne podržava JavaScript. Za bolje rezultate koristite molim preglednik koji ovladava JavaScript.
Thank you
Hvala Vam
You can now close this window
Sada možete zatvoriti ovo okno
Server terminated
Poslužitelj je razriješen
A fatal error has occured during this mirror
Tijekom ovog zrcaljenja je nastala fatalna pogreška

View File

@@ -711,9 +711,9 @@ Log
Window
A&ken
Help
Abi
&Abi
Exit
Välju
&Välju
Load default options
Laadi vaikimisi seaded
Save default options

View File

@@ -372,8 +372,6 @@ Create a Start Page
Create a Start Page
Create a word database of all html pages
Create a word database of all html pages
Build a complete RFC822 mail (MHT/EML) archive of the mirror
Build a complete RFC822 mail (MHT/EML) archive of the mirror
Create error logging and report files
Create error logging and report files
Generate DOS 8-3 filenames ONLY
@@ -422,12 +420,6 @@ Browser identity
Browser identity
Comment to be placed in each HTML file
Comment to be placed in each HTML file
Languages accepted by the browser
Languages accepted by the browser
Additional HTTP headers to be sent in each requests
Additional HTTP headers to be sent in each requests
HTTP referer to be sent for initial URLs
HTTP referer to be sent for initial URLs
Back to starting page
Back to starting page
Save current preferences as default values
@@ -488,8 +480,6 @@ Make an index
Make an index
Make a word database
Make a word database
Build a mail archive
Build a mail archive
Log files
Log files
DOS names (8+3)
@@ -518,12 +508,6 @@ Identity
Identity
HTML footer
HTML footer
Languages
Languages
Additional HTTP Headers
Additional HTTP Headers
Default referer URL
Default referer URL
N# connections
N# connections
Abandon host if error
@@ -946,33 +930,3 @@ Server terminated
Server terminated
A fatal error has occured during this mirror
A fatal error has occured during this mirror
View Documentation
View Documentation
Go To HTTrack Website
Go To HTTrack Website
Go To HTTrack Forum
Go To HTTrack Forum
View License
View License
Beware: you local browser might be unable to browse files with embedded filenames
Beware: you local browser might be unable to browse files with embedded filenames
Recreated HTTrack internal cached resources
Recreated HTTrack internal cached resources
Could not create internal cached resources
Could not create internal cached resources
Could not get the system external storage directory
Could not get the system external storage directory
Could not write to:
Could not write to:
Read-only media (SDCARD)
Read-only media (SDCARD)
No storage media (SDCARD)
No storage media (SDCARD)
HTTrack may not be able to download websites until this problem is fixed
HTTrack may not be able to download websites until this problem is fixed
HTTrack: mirror '%s' stopped!
HTTrack: mirror '%s' stopped!
Click on this notification to restart the interrupted mirror
Click on this notification to restart the interrupted mirror
HTTrack: could not save profile for '%s'!
HTTrack: could not save profile for '%s'!

View File

@@ -671,7 +671,7 @@ EI
File
&Tiedosto
Options
Valinnat
&Valinnat
Log
&Loki
Window
@@ -681,7 +681,7 @@ O&hje
Pause transfer
Pysäytä siirto
Exit
Poistu
&Poistu
Modify options
&Muokkaa valintoja
View log
@@ -713,9 +713,9 @@ Log
Window
&Ikkuna
Help
Ohje
O&hje
Exit
Poistu
&Poistu
Load default options
&Lataa vakioasetukset
Save default options

View File

@@ -420,10 +420,6 @@ Browser identity
Identifiants du Navigateur Internet
Comment to be placed in each HTML file
Commentaire de page placé dans chaque fichier HTML
Languages accepted by the browser
Langues acceptée par le navigateur
Additional HTTP headers to be sent in each requests
En-têtes HTTP additionnels à envoyer dans chaque requête
Back to starting page
Retour à la page de démarrage
Save current preferences as default values
@@ -512,10 +508,6 @@ Identity
Identification
HTML footer
En-tête HTML
Languages
Langues
Additional HTTP Headers
En têtes HTTP additionnels
N# connections
Nombre de connexions
Abandon host if error
@@ -729,7 +721,7 @@ Utiliser les options par d
Save default options
Enregistrer en tant qu'options par défaut
Reset to default options
Initialiser les options par défaut
Charger les options par défaut
Load options...
Charger les options
Save options as...
@@ -751,7 +743,7 @@ Enregistrer &sous...
&Delete...
&Effacer...
&Browse sites...
&Explorer sites...
&Browse sites...
User-defined structure
Définir une structure personnalisée
%n\tName of file without file type (ex: image)\r\n%N\tName of file including file type (ex: image.gif)\r\n%t\tFile type only (ex: gif)\r\n%p\tPath [without ending /] (ex: /someimages)\r\n%h\tHost name (ex: www.someweb.com)\r\n%M\tMD5 URL (128 bits, 32 ascii bytes)\r\n%Q\tMD5 query string (128 bits, 32 ascii bytes)\r\n%q\tMD5 small query string (16 bits, 4 ascii bytes)\r\n\r\n%s?\tShort name (ex: %sN)
@@ -938,41 +930,3 @@ Server terminated
Serveur arrêté
A fatal error has occured during this mirror
Une erreur critique est intervenue durant l'aspiration
View Documentation
Lire la documentation
Go To HTTrack Website
Visiter le site de HTTrack
Go To HTTrack Forum
Visiter le forum de HTTrack
View License
Lire la license
Beware: you local browser might be unable to browse files with embedded filenames
Attention: il se pourrait que votre navigateur soit incapable de lire les fichiers contenant des espaces
Recreated HTTrack internal cached resources
Cache des ressources interne recréé
Could not create internal cached resources
Impossible de créer le cache des ressources interne
Could not get the system external storage directory
Impossible de localuser le système de stockage externe
Could not write to:
Impossible d'écrire dans:
Read-only media (SDCARD)
Média en lecture seule (SDCARD)
No storage media (SDCARD)
Pas de média (SDCARD)
HTTrack may not be able to download websites until this problem is fixed
Il se peut que HTTrack soit incapable de télécharger des sites tant que ce problème n'est pas réglé
HTTrack: mirror '%s' stopped!
HTTrack: miroir '%s' stoppé!
Click on this notification to restart the interrupted mirror
Cliquez sur cette notification pour redémarrer la copie interrompue
HTTrack: could not save profile for '%s'!
HTTrack: impossible de sauver le profil pour '%s'
Build a complete RFC822 mail (MHT/EML) archive of the mirror
Construire une archive email complète (MHT/EML) au format RFC822
HTTP referer to be sent for initial URLs
Champ HTTP referer a envoyer pour les URL initiales
Build a mail archive
Construire une archive mail
Default referer URL
Champ referer par défaut

View File

@@ -3,7 +3,7 @@ Japanese
LANGUAGE_FILE
Japanese
LANGUAGE_ISO
ja
jp
LANGUAGE_AUTHOR
TAPKAL\r\n
LANGUAGE_CHARSET

View File

@@ -3,7 +3,7 @@ Portugu
LANGUAGE_FILE
Portugues-Brasil
LANGUAGE_ISO
pt_BR
pt
LANGUAGE_AUTHOR
Paulo Neto (layoutbr at lexxa.com.br) \r\n
LANGUAGE_CHARSET

View File

@@ -3,7 +3,7 @@ Ukrainian
LANGUAGE_FILE
Ukrainian
LANGUAGE_ISO
uk
ua
LANGUAGE_AUTHOR
Andrij Shevchuk (http://programy.com.ua, http://vic-info.com.ua) \r\n
LANGUAGE_CHARSET

View File

@@ -26,7 +26,7 @@
#include "htsdefines.h"
/* Local definitions */
#include "example-main.h"
#include "example.h"
/*
* Name: main

View File

@@ -16,12 +16,12 @@ Copyright notice:
----------------
HTTrack Website Copier, Offline Browser for Windows and Unix
Copyright (C) Xavier Roche and other contributors
Copyright (C) 1998-2013 Xavier Roche and other contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or any later version.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -29,8 +29,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
along with this program. If not, see <http://www.gnu.org/licenses/>.
========================================================================
MAKEFILE PROJECT : libtest Project Overview

View File

@@ -1,26 +1,27 @@
dnl @synopsis CHECK_ZLIB()
dnl
dnl This macro searches for an installed zlib library. If nothing
dnl was specified when calling configure, it searches first in /usr/local
dnl This macro searches for an installed zlib library. If nothing was
dnl specified when calling configure, it searches first in /usr/local
dnl and then in /usr. If the --with-zlib=DIR is specified, it will try
dnl to find it in DIR/include/zlib.h and DIR/lib/libz.a. If --without-zlib
dnl is specified, the library is not searched at all.
dnl to find it in DIR/include/zlib.h and DIR/lib/libz.a. If
dnl --without-zlib is specified, the library is not searched at all.
dnl
dnl If either the header file (zlib.h) or the library (libz) is not
dnl found, the configuration exits on error, asking for a valid
dnl zlib installation directory or --without-zlib.
dnl found, the configuration exits on error, asking for a valid zlib
dnl installation directory or --without-zlib.
dnl
dnl The macro defines the symbol HAVE_LIBZ if the library is found. You should
dnl use autoheader to include a definition for this symbol in a config.h
dnl file. Sample usage in a C/C++ source is as follows:
dnl The macro defines the symbol HAVE_LIBZ if the library is found. You
dnl should use autoheader to include a definition for this symbol in a
dnl config.h file. Sample usage in a C/C++ source is as follows:
dnl
dnl #ifdef HAVE_LIBZ
dnl #include <zlib.h>
dnl #endif /* HAVE_LIBZ */
dnl
dnl @version $Id$
dnl @category InstalledPackages
dnl @author Loic Dachary <loic@senga.org>
dnl
dnl @version 2004-09-20
dnl @license GPLWithACException
AC_DEFUN([CHECK_ZLIB],
#
@@ -33,17 +34,21 @@ AC_ARG_WITH(zlib,
--without-zlib to disable zlib usage completely],
[if test "$withval" != no ; then
AC_MSG_RESULT(yes)
ZLIB_HOME="$withval"
if test -d "$withval"
then
ZLIB_HOME="$withval"
else
AC_MSG_WARN([Sorry, $withval does not exist, checking usual places])
fi
else
AC_MSG_RESULT(no)
fi], [
AC_MSG_RESULT(yes)
fi])
ZLIB_HOME=/usr/local
if test ! -f "${ZLIB_HOME}/include/zlib.h"
then
ZLIB_HOME=/usr
fi
])
#
# Locate zlib, if wanted

View File

@@ -1,3 +1,5 @@
#SUBDIRS = swf
DevIncludesdir = $(includedir)/httrack
DevIncludes_DATA = \
httrack-library.h \
@@ -47,7 +49,9 @@ libhttrack_la_SOURCES = htscore.c htsparse.c htsback.c htscache.c \
htsmd5.c htszlib.c htswrap.c \
htsmodules.c htscharset.c punycode.c htsencoding.c \
md5.c \
htsmms.c \
minizip/ioapi.c minizip/mztools.c minizip/unzip.c minizip/zip.c \
mmsrip/error.c mmsrip/mms.c \
hts-indextmpl.h htsalias.h htsback.h htsbase.h \
htsbasenet.h htsbauth.h htscache.h htscatchurl.h \
htsconfig.h htscore.h htsparse.h htscoremain.h htsdefines.h \
@@ -57,9 +61,11 @@ libhttrack_la_SOURCES = htscore.c htsparse.c htsback.c htscache.c \
htsopt.h htsrobots.h htsthread.h \
htstools.h htswizard.h htswrap.h htszlib.h \
htsstrings.h httrack-library.h htscharset.h punycode.h htsencoding.h \
htsentities.h htsentities.sh htsbasiccharsets.sh htscodepages.h \
md5.h murmurhash3.h \
minizip/crypt.h minizip/ioapi.h minizip/mztools.h minizip/unzip.h minizip/zip.h
htsentities.h htsentities.sh \
md5.h \
htsmms.h \
minizip/crypt.h minizip/ioapi.h minizip/mztools.h minizip/unzip.h minizip/zip.h \
mmsrip/error.h mmsrip/mms.h
libhttrack_la_LIBADD = $(THREADS_LIBS) $(ZLIB_LIBS) $(OPENSSL_LIBS) $(DL_LIBS) $(SOCKET_LIBS) $(ICONV_LIBS)
libhttrack_la_LDFLAGS = -version-info $(VERSION_INFO)
@@ -71,6 +77,13 @@ EXTRA_DIST = httrack.h webhttrack \
minizip/ChangeLogUnzip \
minizip/iowin32.c \
minizip/iowin32.h \
mmsrip/common.h \
mmsrip/main.c \
mmsrip/COPYING \
mmsrip/AUTHORS \
mmsrip/NEWS \
mmsrip/README \
mmsrip/ChangeLog \
proxy/AUTHORS \
proxy/COPYING \
proxy/changelog.txt \

View File

@@ -15,6 +15,8 @@
@SET_MAKE@
#SUBDIRS = swf
@@ -116,7 +118,7 @@ am_libhttrack_la_OBJECTS = htscore.lo htsparse.lo htsback.lo \
htsrobots.lo htstools.lo htswizard.lo htsalias.lo htsthread.lo \
htsindex.lo htsbauth.lo htsmd5.lo htszlib.lo htswrap.lo \
htsmodules.lo htscharset.lo punycode.lo htsencoding.lo md5.lo \
ioapi.lo mztools.lo unzip.lo zip.lo
htsmms.lo ioapi.lo mztools.lo unzip.lo zip.lo error.lo mms.lo
libhttrack_la_OBJECTS = $(am_libhttrack_la_OBJECTS)
libhttrack_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -344,7 +346,9 @@ libhttrack_la_SOURCES = htscore.c htsparse.c htsback.c htscache.c \
htsmd5.c htszlib.c htswrap.c \
htsmodules.c htscharset.c punycode.c htsencoding.c \
md5.c \
htsmms.c \
minizip/ioapi.c minizip/mztools.c minizip/unzip.c minizip/zip.c \
mmsrip/error.c mmsrip/mms.c \
hts-indextmpl.h htsalias.h htsback.h htsbase.h \
htsbasenet.h htsbauth.h htscache.h htscatchurl.h \
htsconfig.h htscore.h htsparse.h htscoremain.h htsdefines.h \
@@ -354,9 +358,11 @@ libhttrack_la_SOURCES = htscore.c htsparse.c htsback.c htscache.c \
htsopt.h htsrobots.h htsthread.h \
htstools.h htswizard.h htswrap.h htszlib.h \
htsstrings.h httrack-library.h htscharset.h punycode.h htsencoding.h \
htsentities.h htsentities.sh htsbasiccharsets.sh htscodepages.h \
md5.h murmurhash3.h \
minizip/crypt.h minizip/ioapi.h minizip/mztools.h minizip/unzip.h minizip/zip.h
htsentities.h htsentities.sh \
md5.h \
htsmms.h \
minizip/crypt.h minizip/ioapi.h minizip/mztools.h minizip/unzip.h minizip/zip.h \
mmsrip/error.h mmsrip/mms.h
libhttrack_la_LIBADD = $(THREADS_LIBS) $(ZLIB_LIBS) $(OPENSSL_LIBS) $(DL_LIBS) $(SOCKET_LIBS) $(ICONV_LIBS)
libhttrack_la_LDFLAGS = -version-info $(VERSION_INFO)
@@ -367,6 +373,13 @@ EXTRA_DIST = httrack.h webhttrack \
minizip/ChangeLogUnzip \
minizip/iowin32.c \
minizip/iowin32.h \
mmsrip/common.h \
mmsrip/main.c \
mmsrip/COPYING \
mmsrip/AUTHORS \
mmsrip/NEWS \
mmsrip/README \
mmsrip/ChangeLog \
proxy/AUTHORS \
proxy/COPYING \
proxy/changelog.txt \
@@ -542,6 +555,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htsalias.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htsback.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htsbauth.Plo@am__quote@
@@ -560,6 +574,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htsjava.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htslib.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htsmd5.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htsmms.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htsmodules.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htsname.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htsparse.Plo@am__quote@
@@ -574,6 +589,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httrack.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ioapi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mms.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mztools.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxytrack-htsinthash.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxytrack-htsmd5.Po@am__quote@
@@ -638,6 +654,20 @@ zip.lo: minizip/zip.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o zip.lo `test -f 'minizip/zip.c' || echo '$(srcdir)/'`minizip/zip.c
error.lo: mmsrip/error.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT error.lo -MD -MP -MF $(DEPDIR)/error.Tpo -c -o error.lo `test -f 'mmsrip/error.c' || echo '$(srcdir)/'`mmsrip/error.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/error.Tpo $(DEPDIR)/error.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mmsrip/error.c' object='error.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o error.lo `test -f 'mmsrip/error.c' || echo '$(srcdir)/'`mmsrip/error.c
mms.lo: mmsrip/mms.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mms.lo -MD -MP -MF $(DEPDIR)/mms.Tpo -c -o mms.lo `test -f 'mmsrip/mms.c' || echo '$(srcdir)/'`mmsrip/mms.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/mms.Tpo $(DEPDIR)/mms.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mmsrip/mms.c' object='mms.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mms.lo `test -f 'mmsrip/mms.c' || echo '$(srcdir)/'`mmsrip/mms.c
proxytrack-main.o: proxy/main.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(proxytrack_CFLAGS) $(CFLAGS) -MT proxytrack-main.o -MD -MP -MF $(DEPDIR)/proxytrack-main.Tpo -c -o proxytrack-main.o `test -f 'proxy/main.c' || echo '$(srcdir)/'`proxy/main.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/proxytrack-main.Tpo $(DEPDIR)/proxytrack-main.Po

View File

@@ -88,6 +88,7 @@ void hts_lowcase(char *s);
const char *hts_optalias[][4] = {
/* {"","","",""}, */
{"path", "-O", "param1", "output path"},
{"chroot", "-%O", "param1", "default top path"},
{"mirror", "-w", "single", ""},
{"mirror-wizard", "-W", "single", ""},
{"get-files", "-g", "single", ""},
@@ -101,6 +102,7 @@ const char *hts_optalias[][4] = {
{"max-files", "-m", "param", ""},
{"max-size", "-M", "param", ""},
{"max-time", "-E", "param", ""},
{"max-mms-time", "-%m", "param", ""},
{"max-rate", "-A", "param", ""},
{"max-pause", "-G", "param", ""},
{"sockets", "-c", "param", "number of simultaneous connections allowed"},
@@ -122,8 +124,6 @@ const char *hts_optalias[][4] = {
{"list", "-%L", "param1", ""},
{"urllist", "-%S", "param1", ""},
{"language", "-%l", "param1", ""}, {"lang", "-%l", "param1", ""},
{"accept", "-%a", "param1", ""},
{"headers", "-%X", "param1", ""},
{"structure", "-N", "param", ""}, {"user-structure", "-N", "param1", ""},
{"long-names", "-L", "param", ""},
{"keep-links", "-K", "param", ""},
@@ -210,6 +210,7 @@ const char *hts_optalias[][4] = {
{"debug-xfrstats", "-#T", "single", ""},
{"advanced-wait", "-#u", "single", ""},
{"debug-ratestats", "-#Z", "single", ""},
{"exec", "-#!", "param1", ""},
{"fast-engine", "-#X", "single", "Enable fast routines"},
{"debug-overflows", "-#X0", "single", "Attempt to detect buffer overflows"},
{"debug-cache", "-#C", "param1", "List files in the cache"},
@@ -255,6 +256,10 @@ const char *hts_optalias[][4] = {
{"add", "", "param0", "add URLs"},
/* */
/* Specific */
{"user", "-%U", "param1", "output path"},
/* */
/* Internal */
{"catchurl", "--catchurl", "single", "catch complex URL through proxy"},
{"updatehttrack", "--updatehttrack", "single",
@@ -572,11 +577,13 @@ int optinclude_file(const char *name, int *argc, char **argv, char *x_argvblk,
/* Get home directory, '.' if failed */
/* example: /home/smith */
char *hts_gethome(void) {
#ifndef _WIN32_WCE
char *home = getenv("HOME");
if (home)
return home;
else
#endif
return ".";
}

View File

@@ -55,11 +55,17 @@ Please visit our Website: http://www.httrack.com
#ifdef _WIN32
#ifndef __cplusplus
// DOS
#ifndef _WIN32_WCE
#include <process.h> /* _beginthread, _endthread */
#endif
#endif
#else
#endif
#if HTS_USEMMS
#include "htsmms.h"
#endif
#define VT_CLREOL "\33[K"
/* Slot operations */
@@ -73,7 +79,7 @@ struct_back *back_new(int back_max) {
sback->count = back_max;
sback->lnk = (lien_back *) calloct((back_max + 1), sizeof(lien_back));
sback->ready = inthash_new(0);
sback->ready = inthash_new(32767);
sback->ready_size_bytes = 0;
inthash_value_is_malloc(sback->ready, 1);
// init
@@ -401,7 +407,7 @@ int back_done_incache(struct_back * sback) {
// stored (ready) slots
if (sback->ready != NULL) {
#ifndef HTS_NO_BACK_ON_DISK
n += (int) inthash_nitems(sback->ready);
n += inthash_nitems(sback->ready);
#else
struct_inthash_enum e = inthash_enum_new(sback->ready);
inthash_chain *item;
@@ -449,31 +455,6 @@ int back_nsoc_overall(struct_back * sback) {
return n;
}
/* generate temporary file on lien_back */
/* Note: utf-8 */
static int create_back_tmpfile(httrackp * opt, lien_back *const back) {
// do not use tempnam() but a regular filename
back->tmpfile_buffer[0] = '\0';
if (back->url_sav != NULL && back->url_sav[0] != '\0') {
snprintf(back->tmpfile_buffer, sizeof(back->tmpfile_buffer), "%s.z",
back->url_sav);
back->tmpfile = back->tmpfile_buffer;
if (structcheck(back->tmpfile) != 0) {
hts_log_print(opt, LOG_WARNING, "can not create directory to %s",
back->tmpfile);
return -1;
}
} else {
snprintf(back->tmpfile_buffer, sizeof(back->tmpfile_buffer),
"%s/tmp%d.z", StringBuff(opt->path_html_utf8),
opt->state.tmpnameid++);
back->tmpfile = back->tmpfile_buffer;
}
/* OK */
hts_log_print(opt, LOG_TRACE, "produced temporary name %s", back->tmpfile);
return 0;
}
// objet (lien) téléchargé ou transféré depuis le cache
//
// fermer les paramètres de transfert,
@@ -524,11 +505,27 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
back[p].compressed_size = back[p].r.size;
// en mémoire -> passage sur disque
if (!back[p].r.is_write) {
// do not use tempnam() but a regular filename
if (create_back_tmpfile(opt, &back[p]) == 0) {
assert(back[p].tmpfile != NULL);
/* note: tmpfile is utf-8 */
back[p].r.out = FOPEN(back[p].tmpfile, "wb");
#if 1
#ifdef _WIN32
#undef tempnam
#define tempnam _tempnam
#endif
char *const tmp = tempnam(NULL, "httrack_temporaryGzipFile_");
if (tmp != NULL) {
strcpybuff(back[p].tmpfile_buffer, tmp);
free(tmp);
back[p].tmpfile = back[p].tmpfile_buffer;
} else {
back[p].tmpfile = NULL;
}
#else
back[p].tmpfile_buffer[0] = '\0';
back[p].tmpfile = tmpnam(back[p].tmpfile_buffer);
#endif
if (back[p].tmpfile != NULL && back[p].tmpfile[0] != '\0') {
/* note: tmpfile is a local system filename */
back[p].r.out = fopen(back[p].tmpfile, "wb");
if (back[p].r.out) {
if ((back[p].r.adr) && (back[p].r.size > 0)) {
if (fwrite
@@ -544,15 +541,11 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
strcpybuff(back[p].r.msg, "Empty compressed file");
}
} else {
snprintf(back[p].r.msg, sizeof(back[p].r.msg),
"Open error when decompressing (can not create temporary file %s)",
back[p].tmpfile);
back[p].tmpfile[0] = '\0';
back[p].r.statuscode = STATUSCODE_INVALID;
strcpybuff(back[p].r.msg,
"Open error when decompressing (can not create a temporary file)");
}
} else {
snprintf(back[p].r.msg, sizeof(back[p].r.msg),
"Open error when decompressing (can not generate a temporary file)");
}
}
// fermer fichier sortie
@@ -561,7 +554,7 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
back[p].r.out = NULL;
}
// décompression
if (back[p].tmpfile != NULL) {
if (back[p].tmpfile != NULL && back[p].tmpfile[0] != '\0') {
if (back[p].url_sav[0]) {
LLint size;
@@ -711,9 +704,6 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
if (strcmp(back[p].url_fil, "/robots.txt") != 0) {
HTS_STAT.stat_bytes += back[p].r.size;
HTS_STAT.stat_files++;
hts_log_print(opt, LOG_TRACE, "added file %s%s => %s",
back[p].url_adr, back[p].url_fil,
back[p].url_sav != NULL ? back[p].url_sav : "");
}
if ((!back[p].r.notmodified) && (opt->is_update)) {
HTS_STAT.stat_updated_files++; // page modifiée
@@ -1053,12 +1043,9 @@ int back_maydelete(httrackp * opt, cache_back * cache, struct_back * sback,
lien_back tmp;
strcpybuff(tmp.url_adr, back[p].url_adr);
tmp.ka_time_start = back[p].ka_time_start;
if (back_letlive(opt, cache, sback, p)) {
strcpybuff(back[p].url_adr, tmp.url_adr);
back[p].ka_time_start = tmp.ka_time_start;
back[p].status = STATUS_ALIVE; // alive & waiting
assert(back[p].ka_time_start != 0);
hts_log_print(opt, LOG_DEBUG,
"(Keep-Alive): successfully saved #%d (%s)",
back[p].r.debugid, back[p].url_adr);
@@ -1104,15 +1091,12 @@ void back_maydeletehttp(httrackp * opt, cache_back * cache, struct_back * sback,
lien_back tmp;
strcpybuff(tmp.url_adr, back[p].url_adr);
tmp.ka_time_start = back[p].ka_time_start;
deletehttp(&back[q].r); // security check
back_connxfr(&back[p].r, &back[q].r); // transfer live connection settings from p to q
back[q].ka_time_start = back[p].ka_time_start; // refresh
back[p].r.soc = INVALID_SOCKET;
strcpybuff(back[q].url_adr, tmp.url_adr); // address
back[q].ka_time_start = tmp.ka_time_start;
back[q].status = STATUS_ALIVE; // alive & waiting
assert(back[q].ka_time_start != 0);
hts_log_print(opt, LOG_DEBUG,
"(Keep-Alive): successfully preserved #%d (%s)",
back[q].r.debugid, back[q].url_adr);
@@ -1136,7 +1120,6 @@ int back_trylive(httrackp * opt, cache_back * cache, struct_back * sback,
if (i >= 0 && i != p) {
deletehttp(&back[p].r); // security check
back_connxfr(&back[i].r, &back[p].r); // transfer live connection settings from i to p
back[p].ka_time_start = back[i].ka_time_start;
back_delete(opt, cache, sback, i); // delete old slot
back[p].status = STATUS_CONNECTING; // ready to connect
return 1; // success: will reuse live connection
@@ -1309,7 +1292,6 @@ int back_delete(httrackp * opt, cache_back * cache, struct_back * sback,
back[p].url_adr, back[p].url_fil, back[p].url_sav);
}
if (cache != NULL) {
//hts_log_print(opt, LOG_TRACE, "finalizing from back_delete");
back_finalize(opt, cache, sback, p);
}
}
@@ -1701,7 +1683,6 @@ int back_add(struct_back * sback, httrackp * opt, cache_back * cache, char *adr,
// finalize transfer
if (!test) {
if (back[p].r.statuscode > 0) {
hts_log_print(opt, LOG_TRACE, "finalizing in back_add");
back_finalize(opt, cache, sback, p);
}
}
@@ -1910,18 +1891,17 @@ int back_add(struct_back * sback, httrackp * opt, cache_back * cache, char *adr,
// recopier proxy
if ((back[p].r.req.proxy.active = opt->proxy.active)) {
if (StringBuff(opt->proxy.bindhost) != NULL)
back[p].r.req.proxy.bindhost = StringBuff(opt->proxy.bindhost);
strcpybuff(back[p].r.req.proxy.bindhost,
StringBuff(opt->proxy.bindhost));
if (StringBuff(opt->proxy.name) != NULL)
back[p].r.req.proxy.name = StringBuff(opt->proxy.name);
strcpybuff(back[p].r.req.proxy.name, StringBuff(opt->proxy.name));
back[p].r.req.proxy.port = opt->proxy.port;
}
// et user-agent
back[p].r.req.user_agent = StringBuff(opt->user_agent);
back[p].r.req.referer = StringBuff(opt->referer);
back[p].r.req.from = StringBuff(opt->from);
back[p].r.req.lang_iso = StringBuff(opt->lang_iso);
back[p].r.req.accept = StringBuff(opt->accept);
back[p].r.req.headers = StringBuff(opt->headers);
strcpy(back[p].r.req.user_agent, StringBuff(opt->user_agent));
strcpy(back[p].r.req.referer, StringBuff(opt->referer));
strcpy(back[p].r.req.from, StringBuff(opt->from));
strcpy(back[p].r.req.lang_iso, StringBuff(opt->lang_iso));
back[p].r.req.user_agent_send = opt->user_agent_send;
// et http11
back[p].r.req.http11 = back[p].http11;
@@ -1950,6 +1930,26 @@ int back_add(struct_back * sback, httrackp * opt, cache_back * cache, char *adr,
return 0;
}
}
#if HTS_USEMMS
else if (strfield(back[p].url_adr, "mms://")) {
MMSDownloadStruct str;
if (back[p].testmode) {
hts_log_print(opt, LOG_DEBUG,
"error: forbidden test with mms link for back_add");
return -1; // erreur pas de test permis
}
if (back[p].r.req.proxy.active) {
hts_log_print(opt, LOG_WARNING,
"warning: direct connection for mms links (proxy settings ignored)");
}
back[p].status = STATUS_FTP_TRANSFER; // connexion externe
str.pBack = &back[p];
str.pOpt = opt;
launch_mms(&str);
return 0;
}
#endif
#if HTS_USEOPENSSL
else if (strfield(back[p].url_adr, "https://")) { // let's rock
back[p].r.ssl = 1;
@@ -2046,7 +2046,7 @@ int back_add(struct_back * sback, httrackp * opt, cache_back * cache, char *adr,
#if HTS_XCONN
back[p].status = STATUS_CONNECTING; // connexion en cours
#else
back[p].status = STATUS_WAIT_HEADERS; // chargement en tête en cours
back[p].status = 99; // chargement en tête en cours
#endif
else
back[p].status = 1; // chargement fichier
@@ -2112,6 +2112,66 @@ int back_add(struct_back * sback, httrackp * opt, cache_back * cache, char *adr,
}
#if HTS_XGETHOST
#if USE_BEGINTHREAD
// lancement multithread du robot
typedef struct {
httrackp *opt;
char iadr_p[HTS_URLMAXSIZE];
} HostlookupStruct;
void Hostlookup(void *pP) {
HostlookupStruct *const str = (HostlookupStruct *) pP;
httrackp *const opt = str->opt;
char iadr[256];
t_hostent *hp;
t_dnscache *cache;
t_fullhostent fullhostent_buffer;
// recopier (après id:pass)
strcpybuff(iadr, jump_identification(str->iadr_p));
// couper éventuel :
{
char *a;
if ((a = jump_toport(iadr)))
*a = '\0'; // get rid of it
}
// resolve
hp = vxgethostbyname(iadr, &fullhostent_buffer);
hts_mutexlock(&opt->state.lock);
hts_log_print(opt, LOG_DEBUG, "finished resolved: %s", iadr);
for(cache = _hts_cache(opt); cache != NULL; cache = cache->n) {
if (strcmp(cache->iadr, iadr) == 0) {
break;
}
}
if (cache != NULL && cache->host_length == 0) {
if (hp != NULL) {
memset(cache->host_addr, 0, sizeof(cache->host_addr));
memcpy(cache->host_addr, hp->h_addr, hp->h_length);
cache->host_length = hp->h_length;
hts_log_print(opt, LOG_DEBUG, "saved resolved host: %s", iadr);
} else {
cache->host_length = -1;
hts_log_print(opt, LOG_DEBUG, "saved negative resolved host: %s", iadr);
}
} else {
hts_log_print(opt, LOG_DEBUG, "could not save resolved host: %s", iadr);
}
assertf(opt->state.dns_cache_nthreads > 0);
opt->state.dns_cache_nthreads--;
hts_mutexrelease(&opt->state.lock);
freet(pP);
}
#endif
// attendre que le host (ou celui du proxy) ait été résolu
// si c'est un fichier, la résolution est immédiate
// idem pour ftp://
@@ -2120,31 +2180,49 @@ void back_solve(httrackp * opt, lien_back * back) {
assertf(back != NULL);
if ((!strfield(back->url_adr, "file://"))
&& !strfield(back->url_adr, "ftp://")
#if HTS_USEMMS
&& !strfield(back->url_adr, "mms://")
#endif
) {
//## if (back->url_adr[0]!=lOCAL_CHAR) { // qq chose à préparer
const char *a;
if (!(back->r.req.proxy.active))
a = back->url_adr;
else
a = back->r.req.proxy.name;
assertf(a != NULL);
a = jump_protocol(a);
if (check_hostname_dns(a)) {
hts_log_print(opt, LOG_DEBUG, "resolved: %s", a);
} else {
hts_log_print(opt, LOG_DEBUG, "failed to resolve: %s", a);
if (hts_dnstest(opt, a, 1) == 2) { // non encore testé!..
hts_log_print(opt, LOG_DEBUG, "resolving in background: %s", a);
{
HostlookupStruct *str =
(HostlookupStruct *) malloct(sizeof(HostlookupStruct));
if (str != NULL) {
strcpybuff(str->iadr_p, a);
str->opt = opt;
hts_newthread(Hostlookup, str);
}
}
}
//if (hts_dnstest(opt, a, 1) == 2) { // non encore testé!..
// hts_log_print(opt, LOG_DEBUG, "resolving in background: %s", a);
//}
}
}
// détermine si le host a pu être résolu
int host_wait(httrackp * opt, lien_back * back) {
// Always synchronous. No more background DNS resolution
// (does not really improve performances)
return 1;
if ((!strfield(back->url_adr, "file://"))
&& (!strfield(back->url_adr, "ftp://"))
#if HTS_USEMMS
&& (!strfield(back->url_adr, "mms://"))
#endif
) {
//## if (back->url_adr[0]!=lOCAL_CHAR) {
if (!(back->r.req.proxy.active)) {
return (hts_dnstest(opt, back->url_adr, 0));
} else {
return (hts_dnstest(opt, back->r.req.proxy.name, 0));
}
} else
return 1; // prêt, fichier local
}
#endif
@@ -2169,7 +2247,7 @@ static int slot_can_be_finalized(httrackp * opt, const lien_back * back) {
&& !may_be_hypertext_mime(opt, back->r.contenttype, back->url_fil) // may NOT be parseable mime type
/* Has not been added before the heap saw the link, or now exists on heap */
&& (!back->early_add
|| hash_read(opt->hash, back->url_sav, NULL, HASH_STRUCT_FILENAME) >= 0);
|| hash_read(opt->hash, back->url_sav, "", 0, opt->urlhack) >= 0);
}
void back_clean(httrackp * opt, cache_back * cache, struct_back * sback) {
@@ -2191,10 +2269,10 @@ void back_clean(httrackp * opt, cache_back * cache, struct_back * sback) {
//}
/* MANDATORY if we don't want back_fill() to endlessly put the same file on download! */
{
int index = hash_read(opt->hash, back[i].url_sav, NULL, HASH_STRUCT_FILENAME ); // lecture type 0 (sav)
int index = hash_read(opt->hash, back[i].url_sav, "", 0, opt->urlhack); // lecture type 0 (sav)
if (index >= 0) {
opt->liens[index]->pass2 = -1; /* DONE! */
opt->hash->liens[index]->pass2 = -1; /* DONE! */
} else {
hts_log_print(opt, LOG_INFO,
"engine: warning: entry cleaned up, but no trace on heap: %s%s (%s)",
@@ -2251,23 +2329,9 @@ void back_clean(httrackp * opt, cache_back * cache, struct_back * sback) {
if (!back[i].r.keep_alive || back[i].r.soc == INVALID_SOCKET
|| back[i].r.keep_alive_max < 1
|| time_local() >= back[i].ka_time_start + back[i].r.keep_alive_t) {
const char *reason = "unknown";
char buffer[128];
if (!back[i].r.keep_alive) {
reason = "not keep-alive";
} else if (back[i].r.soc == INVALID_SOCKET) {
reason = "closed";
} else if (back[i].r.keep_alive_max < 1) {
reason = "keep-alive-max reached";
} else if (time_local() >= back[i].ka_time_start + back[i].r.keep_alive_t) {
assert(back[i].ka_time_start != 0);
snprintf(buffer, sizeof(buffer), "keep-alive timeout = %ds)",
(int) back[i].r.keep_alive_t);
reason = buffer;
}
hts_log_print(opt, LOG_DEBUG,
"(Keep-Alive): live socket #%d (%s) closed (%s)",
back[i].r.debugid, back[i].url_adr, reason);
"(Keep-Alive): live socket closed #%d (%s)",
back[i].r.debugid, back[i].url_adr);
back_delete(opt, cache, sback, i); // delete backing entry
}
}
@@ -2399,12 +2463,9 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
// vérification de sécurité
if (back[i].r.soc != INVALID_SOCKET) { // hey, you never know..
if (
// Do not endlessly wait when receiving SSL http data (Patrick Pfeifer)
// Do not endlessly wait when receiving SSL http data (Patrick Pfeifer)
#if HTS_USEOPENSSL
!back[i].r.ssl &&
#endif
back[i].status > 0 && back[i].status < 1000) {
if (!(back[i].r.ssl && back[i].status > 0 && back[i].status < 1000)) {
do_wait = 1;
// noter socket read
@@ -2425,6 +2486,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
nfds = back[i].r.soc;
}
}
#endif
} else {
back[i].r.statuscode = STATUSCODE_CONNERROR;
if (back[i].status == STATUS_CONNECTING)
@@ -2589,7 +2651,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
back[i].url_adr, back[i].url_fil,
back[i].referer_adr, back[i].referer_fil,
&back[i].r);
back[i].status = STATUS_WAIT_HEADERS; // attendre en tête maintenant
back[i].status = 99; // attendre en tête maintenant
}
}
// attente gethostbyname
@@ -2711,7 +2773,6 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
back_set_finished(sback, i);
// finalize transfer
if (back[i].r.statuscode > 0) {
hts_log_print(opt, LOG_TRACE, "finalizing ftp");
back_finalize(opt, cache, sback, i);
}
}
@@ -2722,7 +2783,6 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
back_set_finished(sback, i);
// finalize transfer
if (back[i].r.statuscode > 0) {
hts_log_print(opt, LOG_TRACE, "finalizing ftp");
back_finalize(opt, cache, sback, i);
}
} else if ((back[i].status > 0) && (back[i].status < 1000)) { // en réception http
@@ -2780,9 +2840,25 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
(strfield
(get_ext(catbuff, back[i].url_sav), "gz") == 0)
) {
if (create_back_tmpfile(opt, &back[i]) == 0) {
assert(back[i].tmpfile != NULL);
/* note: tmpfile is utf-8 */
#if 1
#ifdef _WIN32
#undef tempnam
#define tempnam _tempnam
#endif
char *const tmp =
tempnam(NULL, "httrack_temporaryGzipFile_");
if (tmp != NULL) {
strcpybuff(back[i].tmpfile_buffer, tmp);
free(tmp);
back[i].tmpfile = back[i].tmpfile_buffer;
} else {
back[i].tmpfile = NULL;
}
#else
back[i].tmpfile_buffer[0] = '\0';
back[i].tmpfile = tmpnam(back[p].tmpfile_buffer);
#endif
if (back[i].tmpfile != NULL && back[i].tmpfile[0]) {
if ((back[i].r.out =
FOPEN(back[i].tmpfile, "wb")) == NULL) {
last_errno = errno;
@@ -2823,18 +2899,12 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
"* * Fatal write error, giving up");
}
back[i].r.is_write = 0; // erreur, abandonner
back[i].status = STATUS_READY; // terminé
back_set_finished(sback, i);
if (back[i].r.soc != INVALID_SOCKET) {
deletehttp(&back[i].r);
back[i].r.soc = INVALID_SOCKET;
}
} else {
#ifndef _WIN32
chmod(back[i].url_sav, HTS_ACCESS_FILE);
#endif
/* create a temporary reference file in case of broken mirror */
if (back[i].r.out != NULL && opt->cache != 0) {
if (back[i].r.out != NULL) {
if (back_serialize_ref(opt, &back[i]) != 0) {
hts_log_print(opt, LOG_WARNING,
"Could not create temporary reference file for %s%s",
@@ -2906,6 +2976,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
} else
retour_fread =
(int) http_xfread1(&(back[i].r), (int) max_read_bytes);
// retour_fread=http_fread1(&(back[i].r));
} else
retour_fread = READ_EOF; // interruption ou annulation interne (peut ne pas être une erreur)
@@ -2972,7 +3043,6 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
// finalize transfer
if (back[i].r.statuscode > 0 && !IS_DELAYED_EXT(back[i].url_sav)
) {
hts_log_print(opt, LOG_TRACE, "finalizing regular file");
back_finalize(opt, cache, sback, i);
}
@@ -3130,7 +3200,6 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
// finalize transfer if not temporary
if (!IS_DELAYED_EXT(back[i].url_sav)) {
hts_log_print(opt, LOG_TRACE, "finalizing at chunk end");
back_finalize(opt, cache, sback, i);
} else {
if (back[i].r.statuscode == HTTP_OK) {
@@ -3594,7 +3663,6 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
// finalize
//file_notify(back[i].url_adr, back[i].url_fil, back[i].url_sav, 0, 0, back[i].r.notmodified); // not modified
if (back[i].r.statuscode > 0) {
hts_log_print(opt, LOG_TRACE, "finalizing after cache load");
back_finalize(opt, cache, sback, i);
}
#if DEBUGCA
@@ -3628,7 +3696,6 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
back_set_finished(sback, i);
// finalize
if (back[i].r.statuscode > 0) {
hts_log_print(opt, LOG_TRACE, "finalizing redirect & 4xx");
back_finalize(opt, cache, sback, i);
}
#endif
@@ -3657,7 +3724,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
back[i].url_sav, 0, 1,
back[i].r.notmodified);
back[i].r.out = FOPEN(fconv(catbuff, back[i].url_sav), "ab"); // append
if (back[i].r.out && opt->cache != 0) {
if (back[i].r.out) {
back[i].r.is_write = 1; // écrire
back[i].r.size = sz; // déja écrit
back[i].r.statuscode = HTTP_OK; // Forcer 'OK'
@@ -3755,7 +3822,6 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
&& (back[i].r.adr = (char *) malloct(2))) {
back[i].r.adr[0] = 0;
}
hts_log_print(opt, LOG_TRACE, "finalizing empty");
back_finalize(opt, cache, sback, i);
} else if (!back[i].r.is_chunk) { // pas de chunk
//if (back[i].r.http11!=2) { // pas de chunk
@@ -3917,8 +3983,9 @@ int back_checksize(httrackp * opt, lien_back * eback, int check_only_totalsize)
if (size_to_test >= 0) {
/* Interdiction taille par le wizard? */
if (hts_testlinksize(opt, eback->url_adr, eback->url_fil,
size_to_test / 1024) == -1) {
if (hts_testlinksize
(opt, eback->url_adr, eback->url_fil,
eback->r.totalsize / 1024) == -1) {
return 0; /* interdit */
}

View File

@@ -138,6 +138,12 @@ int host_wait(httrackp * opt, lien_back * sback);
int back_checksize(httrackp * opt, lien_back * eback, int check_only_totalsize);
int back_checkmirror(httrackp * opt);
#if HTS_XGETHOST
#if USE_BEGINTHREAD
void Hostlookup(void *iadr_p);
#endif
#endif
#endif
#endif

View File

@@ -67,12 +67,10 @@ extern "C" {
#ifdef __GNUC__
#define HTS_UNUSED __attribute__ ((unused))
#define HTS_STATIC static __attribute__ ((unused))
#define HTS_INLINE __inline__
#define HTS_PRINTF_FUN(fmt, arg) __attribute__ ((format (printf, fmt, arg)))
#else
#define HTS_UNUSED
#define HTS_STATIC static
#define HTS_INLINE
#define HTS_PRINTF_FUN(fmt, arg)
#endif
#endif
@@ -111,6 +109,7 @@ extern "C" {
extern HTSEXT_API t_abortLog abortLog__;
#define abortLog(a) abortLog__(a, __FILE__, __LINE__)
#define _ ,
#ifndef _WIN32_WCE
#define abortLogFmt(a) do { \
FILE* fp = fopen("CRASH.TXT", "wb"); \
if (!fp) fp = fopen("/tmp/CRASH.TXT", "wb"); \
@@ -127,6 +126,11 @@ extern "C" {
fclose(fp); \
} \
} while(0)
#else
#define abortLogFmt(a) do { \
XCEShowMessageA("HTTrack " HTTRACK_VERSIONID " closed at '" __FILE__ "', line %d\r\nReason:\r\n%s\r\n", __LINE__, a); \
} while(0)
#endif
#define assertf(exp) do { \
if (! ( exp ) ) { \
@@ -134,6 +138,7 @@ extern "C" {
if (htsCallbackErr != NULL) { \
htsCallbackErr("assert failed: " #exp, __FILE__ , __LINE__ ); \
} \
assert(exp); \
abort(); \
} \
} while(0)

View File

@@ -40,6 +40,7 @@ Please visit our Website: http://www.httrack.com
#include <winsock2.h>
#else
#ifndef _WIN32_WCE
#undef HTS_USESCOPEID
#define WIN32_LEAN_AND_MEAN
// KB955045 (http://support.microsoft.com/kb/955045)
@@ -51,6 +52,10 @@ Please visit our Website: http://www.httrack.com
#include <Wspiapi.h>
//#include <winsock2.h>
//#include <tpipv6.h>
#else
#include <winsock2.h>
#include <socket.h>
#endif
#endif

View File

@@ -1,59 +0,0 @@
#!/bin/bash
#
# Change this to download files
if false; then
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-*.TXT" | lftp
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP*.TXT" | lftp
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP*.TXT" | lftp
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP*.TXT" | lftp
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MISC/CP*.TXT" | lftp
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8*.TXT" | lftp
rm -f CP932.TXT CP936.TXT CP949.TXT CP950.TXT
fi
# Produce code
printf "/** GENERATED FILE ($0), DO NOT EDIT **/\n\n"
for i in *.TXT ; do
echo "processing $i" >&2
grep -vE "^(#|$)" $i | grep -E "^0x" | sed -e 's/[[:space:]]/ /g' | cut -f1,2 -d' ' | \
(
unset arr
while read LINE ; do
from=$[$(echo $LINE | cut -f1 -d' ')]
if ! test -n "$from"; then
echo "error with $i" >&2
exit 1
elif test $from -ge 256; then
echo "out-of-range ($LINE) with $i" >&2
exit 1
fi
to=$(echo $LINE | cut -f2 -d' ')
arr[$from]=$to
done
name=$(echo $i | tr 'A-Z' 'a-z' | tr '-' '_' | sed -e 's/\.txt//' -e 's/8859/iso_8859/')
printf "/* Table for $i */\nstatic const hts_UCS4 table_${name}[256] = {\n "
i=0
while test "$i" -lt 256; do
if test "$i" -gt 0; then
printf ", "
if test $[${i}%8] -eq 0; then
printf "\n "
fi
fi
value=${arr[$i]:-0}
printf "0x%04x" $value
i=$[${i}+1]
done
printf " };\n\n"
)
echo "processed $i" >&2
done
# Indexes
printf "static const struct {\n const char *name;\n const hts_UCS4 *table;\n} table_mappings[] = {\n"
for i in *.TXT ; do
name=$(echo $i | tr 'A-Z' 'a-z' | tr '-' '_' | sed -e 's/\.txt//' -e 's/8859/iso_8859/')
printf " { \"$(echo $name | tr -d '_')\", table_${name} },\n"
done
printf " { NULL, NULL }\n};\n"

View File

@@ -128,23 +128,23 @@ int cookie_del(t_cookie * cookie, char *cook_name, char *domain, char *path) {
// Matches wildcard cookie domains that start with a dot
// chk_dom: the domain stored in the cookie (potentially wildcard).
// domain: query domain
static int cookie_cmp_wildcard_domain(char *chk_dom, char *domain) {
int n = strlen(chk_dom);
int m = strlen(domain);
int l = n < m ? n : m;
int i;
for (i = l - 1; i >= 0; i--) {
if (chk_dom[n - i - 1] != domain[m - i - 1]) {
return 1;
int cookie_cmp_wildcard_domain(char *chk_dom, char *domain) {
int n = strlen(chk_dom);
int m = strlen(domain);
int l = n < m ? n : m;
int i;
for (i = l - 1; i >= 0; i--) {
if (chk_dom[n - i - 1] != domain[m - i - 1]) {
return 1;
}
}
if (m < n && chk_dom[0] == '.') {
return 0;
}
else if (m != n) {
return 1;
}
}
if (m < n && chk_dom[0] == '.') {
return 0;
}
else if (m != n) {
return 1;
}
return 0;
}

View File

@@ -40,7 +40,9 @@ Please visit our Website: http://www.httrack.com
#include "htsbase.h"
#include "htsnet.h"
#include "htslib.h"
#ifndef _WIN32_WCE
#include <fcntl.h>
#endif
#ifdef _WIN32
#else
#include <arpa/inet.h>

View File

@@ -49,40 +49,6 @@ int hts_isStringAscii(const char *s, size_t size) {
return 1;
}
#define IS_ALNUM(C) ( ((C) >= 'A' && (C) <= 'Z') || ((C) >= 'a' && (C) <= 'z') || ((C) >= '0' && (C) <= '9') )
#define CHAR_LOWER(C) ( ((C) >= 'A' && (C) <= 'Z') ? ((C) + 'a' - 'A') : (C) )
static int hts_equalsAlphanum(const char *a, const char *b) {
size_t i, j;
for(i = 0, j = 0;; i++, j++) {
/* Skip non-alnum */
for(; a[i] != '\0' && !IS_ALNUM(a[i]); i++) ;
for(; b[j] != '\0' && !IS_ALNUM(b[j]); j++) ;
/* Compare */
if (CHAR_LOWER(a[i]) != CHAR_LOWER(b[j])) {
break;
}
/* End of string ? (note: a[i] == b[j]) */
else if (a[i] == '\0') {
return 1;
}
}
return 0;
}
#undef IS_ALNUM
#undef CHAR_LOWER
/* Copy the memory region [s .. s + size - 1 ] as a \0-terminated string. */
static char *hts_stringMemCopy(const char *s, size_t size) {
char *dest = malloc(size + 1);
if (dest != NULL) {
memcpy(dest, s, size);
dest[size] = '\0';
return dest;
}
return NULL;
}
#ifdef _WIN32
typedef struct wincodepage_t wincodepage_t;
@@ -241,17 +207,45 @@ static const wincodepage_t codepages[] = {
UINT hts_getCodepage(const char *name) {
int id;
#define IS_ALNUM(C) ( ((C) >= 'A' && (C) <= 'Z') || ((C) >= 'a' && (C) <= 'z') || ((C) >= '0' && (C) <= '9') )
#define CHAR_LOWER(C) ( ((C) >= 'A' && (C) <= 'Z') ? ((C) + 'a' - 'A') : (C) )
for(id = 0; codepages[id].name != NULL; id++) {
int i, j;
/* Compare the two strings, lowercase and alphanum only (ISO88591 == iso-8859-1) */
if (hts_equalsAlphanum(name, codepages[id].name)) {
return codepages[id].codepage;
const char *a = name, *b = codepages[id].name;
for(i = 0, j = 0;; i++, j++) {
/* Skip non-alnum */
for(; a[i] != '\0' && !IS_ALNUM(a[i]); i++) ;
for(; b[j] != '\0' && !IS_ALNUM(b[j]); j++) ;
/* Compare */
if (CHAR_LOWER(a[i]) != CHAR_LOWER(b[j])) {
break;
}
/* End of string ? (note: a[i] == b[j]) */
else if (a[i] == '\0') {
return codepages[id].codepage;
}
}
}
#undef IS_ALNUM
#undef CHAR_LOWER
/* Not found */
return 0;
}
static char *strndup(const char *s, size_t size) {
char *dest = malloc(size + 1);
if (dest != NULL) {
memcpy(dest, s, size);
dest[size] = '\0';
return dest;
}
return NULL;
}
LPWSTR hts_convertStringToUCS2(const char *s, int size, UINT cp, int *pwsize) {
/* Size in wide chars of the output */
const int wsize = MultiByteToWideChar(cp, 0, (LPCSTR) s, size, NULL, 0);
@@ -308,11 +302,11 @@ char *hts_convertUCS2StringToUTF8(LPWSTR woutput, int wsize) {
char *hts_convertStringCPToUTF8(const char *s, size_t size, UINT cp) {
/* Empty string ? */
if (size == 0) {
return hts_stringMemCopy(s, size);
return strndup(s, size);
}
/* Already UTF-8 ? */
if (cp == CP_UTF8 || hts_isStringAscii(s, size)) {
return hts_stringMemCopy(s, size);
return strndup(s, size);
}
/* Other (valid) charset */
else if (cp != 0) {
@@ -335,11 +329,11 @@ char *hts_convertStringCPToUTF8(const char *s, size_t size, UINT cp) {
char *hts_convertStringCPFromUTF8(const char *s, size_t size, UINT cp) {
/* Empty string ? */
if (size == 0) {
return hts_stringMemCopy(s, size);
return strndup(s, size);
}
/* Already UTF-8 ? */
if (cp == CP_UTF8 || hts_isStringAscii(s, size)) {
return hts_stringMemCopy(s, size);
return strndup(s, size);
}
/* Other (valid) charset */
else if (cp != 0) {
@@ -378,65 +372,18 @@ char *hts_convertStringSystemToUTF8(const char *s, size_t size) {
#else
#include <errno.h>
#if ( defined(HTS_USEICONV) && ( HTS_USEICONV == 0 ) )
#define DISABLE_ICONV
#endif
#ifndef DISABLE_ICONV
#include <iconv.h>
#else
#include "htscodepages.h"
/* decode from a codepage to UTF-8 */
static char* hts_codepageToUTF8(const char *codepage, const char *s) {
/* find the given codepage */
size_t i;
for(i = 0 ; table_mappings[i].name != NULL
&& !hts_equalsAlphanum(table_mappings[i].name, codepage) ; i++) ;
/* found ; decode */
if (table_mappings[i].name != NULL) {
size_t j, k;
char *dest = NULL;
size_t capa = 0;
#define MAX_UTF 8
for(j = 0, k = 0 ; s[j] != '\0' ; j++) {
const unsigned char c = (unsigned char) s[j];
const hts_UCS4 uc = table_mappings[i].table[c];
const size_t max = k + MAX_UTF;
if (capa < max) {
for(capa = 16 ; capa < max ; capa <<= 1) ;
dest = realloc(dest, capa);
if (dest == NULL) {
return NULL;
}
}
if (dest != NULL) {
const size_t len = hts_writeUTF8(uc, &dest[k], MAX_UTF);
k += len;
assert(k < capa);
}
}
dest[k] = '\0';
return dest;
#undef MAX_UTF
}
return NULL;
}
#endif
static char *hts_convertStringCharset(const char *s, size_t size,
static char *hts_convertStringToUTF8_(const char *s, size_t size,
const char *to, const char *from) {
/* Empty string ? */
if (size == 0) {
return strdup("");
}
/* Already on correct charset ? */
if (hts_equalsAlphanum(from, to)) {
return hts_stringMemCopy(s, size);
if (strcasecmp(from, to) == 0) {
return strndup(s, size);
}
#ifndef DISABLE_ICONV
/* Find codepage */
else {
const iconv_t cp = iconv_open(to, from);
@@ -495,12 +442,6 @@ static char *hts_convertStringCharset(const char *s, size_t size,
return outbuf;
}
}
#else
/* Limited codepage decoding support only. */
if (hts_isCharsetUTF8(to)) {
return hts_codepageToUTF8(from, s);
}
#endif
/* Error, charset not found! */
return NULL;
@@ -513,11 +454,11 @@ char *hts_convertStringToUTF8(const char *s, size_t size, const char *charset) {
}
/* Already UTF-8 ? */
if (hts_isCharsetUTF8(charset) || hts_isStringAscii(s, size)) {
return hts_stringMemCopy(s, size);
return strndup(s, size);
}
/* Find codepage */
else {
return hts_convertStringCharset(s, size, "utf-8", charset);
return hts_convertStringToUTF8_(s, size, "utf-8", charset);
}
}
@@ -528,11 +469,11 @@ char *hts_convertStringFromUTF8(const char *s, size_t size, const char *charset)
}
/* Already UTF-8 ? */
if (hts_isCharsetUTF8(charset) || hts_isStringAscii(s, size)) {
return hts_stringMemCopy(s, size);
return strndup(s, size);
}
/* Find codepage */
else {
return hts_convertStringCharset(s, size, charset, "utf-8");
return hts_convertStringToUTF8_(s, size, charset, "utf-8");
}
}
@@ -1192,26 +1133,6 @@ hts_UCS4* hts_convertUTF8StringToUCS4(const char *s, size_t size, size_t *nChars
return dest;
}
int hts_isStringUTF8(const char *s, size_t size) {
const unsigned char *const data = (const unsigned char*) s;
size_t i;
for(i = 0 ; i < size ; ) {
/* Reader: can read bytes up to j */
#define RD ( i < size ? data[i++] : -1 )
/* Writer: upon error, return FFFD (replacement character) */
#define WR(C) if ((C) == -1) { return 0; }
/* Read Unicode character. */
READ_UNICODE(RD, WR);
#undef RD
#undef WR
}
return 1;
}
char *hts_convertUCS4StringToUTF8(const hts_UCS4 *s, size_t nChars) {
size_t i;
char *dest = NULL;

View File

@@ -85,11 +85,6 @@ extern char *hts_getCharsetFromMeta(const char *html, size_t size);
**/
extern int hts_isStringAscii(const char *s, size_t size);
/**
* Is the given string an UTF-8 string ?
**/
extern int hts_isStringUTF8(const char *s, size_t size);
/**
* Is the given charset the UTF-8 charset ?
**/

File diff suppressed because it is too large Load Diff

View File

@@ -51,6 +51,9 @@ Please visit our Website: http://www.httrack.com
// nom par défaut pour / en ftp
#define DEFAULT_FTP "index.txt"
// nom par défaut pour / en mms
#define DEFAULT_MMS "default.avi"
// extension par défaut pour fichiers n'en ayant pas
#define DEFAULT_EXT ".html"
#define DEFAULT_EXT_SHORT ".htm"

View File

@@ -33,7 +33,9 @@ Please visit our Website: http://www.httrack.com
/* Internal engine bytecode */
#define HTS_INTERNAL_BYTECODE
#ifndef _WIN32_WCE
#include <fcntl.h>
#endif
#include <ctype.h>
/* File defs */
@@ -169,7 +171,6 @@ RUN_CALLBACK0(opt, end); \
if (template_header) { freet(template_header); template_header=NULL; } \
if (template_body) { freet(template_body); template_body=NULL; } \
if (template_footer) { freet(template_footer); template_footer=NULL; } \
hash_free(&hash); \
clearCallbacks(&opt->state.callbacks); \
/*structcheck_init(-1);*/ \
} while(0)
@@ -226,7 +227,7 @@ strcpybuff(liens[lien_tot]->adr,A); \
strcpybuff(liens[lien_tot]->fil,F); \
strcpybuff(liens[lien_tot]->sav,S); \
liens_record_sav_len(liens[lien_tot]); \
hash_write(hashptr,lien_tot); \
hash_write(hashptr,lien_tot,NORM); \
} \
}
@@ -261,7 +262,7 @@ int httpmirror(char *url1, httrackp * opt) {
int lien_tot = 0; // nombre de liens pour le moment
lien_url **liens = NULL; // les pointeurs sur les liens
hash_struct hash; // système de hachage, accélère la recherche dans les liens
hash_struct *const hashptr = &hash;
hash_struct *hashptr = &hash;
t_cookie BIGSTK cookie; // gestion des cookies
int lien_max = 0;
size_t lien_size = 0; // octets restants dans buffer liens dispo
@@ -312,6 +313,7 @@ int httpmirror(char *url1, httrackp * opt) {
robots_wizard BIGSTK robots; // gestion robots.txt
inthash cache_hashtable = NULL;
inthash cache_tests = NULL;
int cache_hash_size = 0;
//
char *template_header = NULL, *template_body = NULL, *template_footer = NULL;
@@ -394,8 +396,10 @@ int httpmirror(char *url1, httrackp * opt) {
cache.ptr_ant = cache.ptr_last = 0; // pointeur pour anticiper
// initialiser hash cache
cache_hashtable = inthash_new(0);
cache_tests = inthash_new(0);
if (!cache_hash_size)
cache_hash_size = HTS_HASH_SIZE;
cache_hashtable = inthash_new(cache_hash_size);
cache_tests = inthash_new(cache_hash_size);
if (cache_hashtable == NULL || cache_tests == NULL) {
printf("PANIC! : Not enough memory [%d]\n", __LINE__);
filters[0] = NULL; // uniquement a cause du warning de XH_extuninit
@@ -444,14 +448,15 @@ int httpmirror(char *url1, httrackp * opt) {
// initialiser ptr et lien_tot
ptr = 0;
lien_tot = 0;
// initialiser hachage
hash_init(&hash, opt->urlhack);
// note: we need a cast because of the const
hash.liens = (const lien_url **) liens;
{
int i;
// we need it
opt->liens = liens;
for(i = 0; i < HTS_HASH_SIZE; i++)
hash.hash[0][i] = hash.hash[1][i] = hash.hash[2][i] = -1; // pas d'entrées
hash.liens = liens;
hash.max_lien = 0;
}
// copier adresse(s) dans liste des adresses
{
@@ -827,18 +832,16 @@ int httpmirror(char *url1, httrackp * opt) {
// recopier proxy
if ((r.req.proxy.active = opt->proxy.active)) {
if (StringBuff(opt->proxy.bindhost) != NULL)
r.req.proxy.bindhost = StringBuff(opt->proxy.bindhost);
strcpybuff(r.req.proxy.bindhost, StringBuff(opt->proxy.bindhost));
if (StringBuff(opt->proxy.name) != NULL)
r.req.proxy.name = StringBuff(opt->proxy.name);
strcpybuff(r.req.proxy.name, StringBuff(opt->proxy.name));
r.req.proxy.port = opt->proxy.port;
}
// et user-agent
r.req.user_agent = StringBuff(opt->user_agent);
r.req.referer = StringBuff(opt->referer);
r.req.from = StringBuff(opt->from);
r.req.lang_iso = StringBuff(opt->lang_iso);
r.req.accept = StringBuff(opt->accept);
r.req.headers = StringBuff(opt->headers);
strcpy(r.req.user_agent, StringBuff(opt->user_agent));
strcpy(r.req.referer, StringBuff(opt->referer));
strcpy(r.req.from, StringBuff(opt->from));
strcpy(r.req.lang_iso, StringBuff(opt->lang_iso));
r.req.user_agent_send = opt->user_agent_send;
if (!error) {
@@ -1036,7 +1039,7 @@ int httpmirror(char *url1, httrackp * opt) {
if ((is_hypertext_mime(opt, r.contenttype, urlfil))
/* Is HTML or Js, .. */
/* NO - real media is real media, not HTML */
/* NO - real media is real media, and mms is mms, not HTML */
/*|| (may_be_hypertext_mime(r.contenttype, urlfil) && (r.adr) ) */
/* Is real media, .. */
) {
@@ -2193,6 +2196,34 @@ int httpmirror(char *url1, httrackp * opt) {
cache.zipOutput = NULL;
}
}
#if DEBUG_HASH
// noter les collisions
{
int i;
int empty1 = 0, empty2 = 0, empty3 = 0;
for(i = 0; i < HTS_HASH_SIZE; i++) {
if (hash.hash[0][i] == -1)
empty1++;
if (hash.hash[1][i] == -1)
empty2++;
if (hash.hash[2][i] == -1)
empty3++;
}
printf("\n");
printf("Debug info: Hash-table report\n");
printf("Number of files entered: %d\n", hashnumber);
printf("Table size: %d\n", HTS_HASH_SIZE);
printf("\n");
printf("Longest chain sav: %d, empty: %d\n", longest_hash[0],
empty1);
printf("Longest chain adr,fil: %d, empty: %d\n", longest_hash[1],
empty2);
printf("Longest chain former_adr/fil: %d, empty: %d\n", longest_hash[2],
empty3);
printf("\n");
}
#endif
// fin afficher résumé dans log
// ending
@@ -2955,18 +2986,6 @@ static void postprocess_file(httrackp * opt, const char *save, const char *adr,
fopen(fconcat
(OPT_GET_BUFF(opt), StringBuff(opt->path_html), "index.mht"),
"wb");
(void) unlink(fconcat(OPT_GET_BUFF(opt), StringBuff(opt->path_html),
"index.eml"));
#ifndef _WIN32
if (symlink("index.mht",
fconcat(OPT_GET_BUFF(opt), StringBuff(opt->path_html),
"index.eml")) != 0) {
if (errno != EPERM) {
hts_log_print(opt, LOG_WARNING | LOG_ERRNO,
"could not create symbolic link from index.mht to index.eml");
}
}
#endif
if (opt->state.mimefp != NULL) {
char BIGSTK rndtmp[1024], currtime[256];
@@ -3235,12 +3254,12 @@ int back_fill(struct_back * sback, httrackp * opt, cache_back * cache,
// Why in hell did I do that ?
//if (ok && liens[p]->sav != NULL && liens[p]->sav[0] != '\0'
// && hash_read(opt->hash,liens[p]->sav,NULL,HASH_STRUCT_FILENAME ) >= 0) // lookup in liens_record
// && hash_read(opt->hash,liens[p]->sav,"",0,opt->urlhack) >= 0) // lookup in liens_record
//{
// ok = 0;
//}
if (liens[p]->sav == NULL || liens[p]->sav[0] == '\0'
|| hash_read(opt->hash, liens[p]->sav, NULL, HASH_STRUCT_FILENAME ) < 0) {
|| hash_read(opt->hash, liens[p]->sav, "", 0, opt->urlhack) < 0) {
ok = 0;
}
// note: si un backing est fini, il reste en mémoire jusqu'à ce que
@@ -3291,7 +3310,11 @@ int read_stdin(char *s, int max) {
#ifdef _WIN32
int check_stdin(void) {
#ifndef _WIN32_WCE
return (_kbhit());
#else
return 0;
#endif
}
#else
int check_flot(T_SOC s) {
@@ -3575,6 +3598,11 @@ HTSEXT_API int copy_htsopt(const httrackp * from, httrackp * to) {
if (from->maxtime > -1)
to->maxtime = from->maxtime;
#if HTS_USEMMS
if (from->mms_maxtime > -1)
to->mms_maxtime = from->mms_maxtime;
#endif
if (from->maxrate > -1)
to->maxrate = from->maxrate;
@@ -3768,7 +3796,7 @@ int htsAddLink(htsmoduleStruct * str, char *link) {
//
// On part de la fin et on essaye de se presser (économise temps machine)
{
int i = hash_read(hashptr, save, NULL, HASH_STRUCT_FILENAME ); // lecture type 0 (sav)
int i = hash_read(hashptr, save, "", 0, opt->urlhack); // lecture type 0 (sav)
if (i >= 0) {
liens[i]->depth = maximum(liens[i]->depth, prio_fix);

View File

@@ -42,8 +42,12 @@ Please visit our Website: http://www.httrack.com
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WIN32
#ifndef _WIN32_WCE
#include <conio.h>
#endif
#ifndef _WIN32_WCE
#include <direct.h>
#endif
#else
#ifndef _WIN32
#include <unistd.h>
@@ -150,6 +154,8 @@ struct lien_url {
char *cod; // chemin codebase éventuel si classe java
char *former_adr; // adresse initiale (avant éventuel moved), peut être nulle
char *former_fil; // nom du fichier distant initial (avant éventuel moved), peut être nul
// pour optimisation:
int hash_next[3]; // prochain lien avec même valeur hash
};
// chargement de fichiers en 'arrière plan'
@@ -254,19 +260,9 @@ struct cache_back {
typedef struct hash_struct hash_struct;
#endif
struct hash_struct {
/* Links big array reference */
const lien_url **liens;
/* Savename (case insensitive ; lowercased) */
inthash sav;
/* Address and path */
inthash adrfil;
/* Former address and path */
inthash former_adrfil;
/** Buffers **/
int normalized;
char normfil[HTS_URLMAXSIZE * 2];
char normfil2[HTS_URLMAXSIZE * 2];
char catbuff[CATBUFF_SIZE];
lien_url **liens; // pointeur sur liens
int max_lien; // indice le plus grand rencontré
int hash[3][HTS_HASH_SIZE]; // tables pour sav/adr-fil/former_adr-former_fil
};
#ifndef HTS_DEF_FWSTRUCT_filecreate_params

View File

@@ -104,19 +104,6 @@ extern int IPV6_resolver;
} \
} while(0)
#ifdef HTS_CRASH_TEST
static __attribute__ ((noinline)) void fourty_two(void) {
char *const ptr = (char*) (uintptr_t) 0x42;
(*ptr)++;
}
static __attribute__ ((noinline)) void do_really_crash(void) {
fourty_two();
}
static __attribute__ ((noinline)) void do_crash(void) {
do_really_crash();
}
#endif
HTSEXT_API int hts_main(int argc, char **argv) {
httrackp *opt = hts_create_opt();
int ret = hts_main2(argc, argv, opt);
@@ -141,6 +128,13 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
// the parametres
int httrack_logmode = 3; // ONE log file
#ifndef _WIN32
#ifndef HTS_DO_NOT_USE_UID
int switch_uid = -1, switch_gid = -1; /* setuid/setgid */
#endif
int switch_chroot = 0; /* chroot ? */
#endif
//
ensureUrlCapacity(url, url_sz, 65536);
// Create options
@@ -1386,18 +1380,10 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
break;
//
case 'z':
if (opt->debug > LOG_INFO) {
opt->debug = LOG_DEBUG; /* -Zz */
} else {
opt->debug = LOG_INFO;
}
opt->debug = LOG_INFO;
break; // petit debug
case 'Z':
if (opt->debug >= LOG_DEBUG) {
opt->debug = LOG_TRACE; /* -Zz */
} else {
opt->debug = LOG_DEBUG;
}
opt->debug = LOG_DEBUG;
break; // GROS debug
//
case '&':
@@ -1550,6 +1536,13 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
com++;
}
break;
#if HTS_USEMMS
case 'm':
sscanf(com + 1, "%d", &opt->mms_maxtime);
while(isdigit((unsigned char) *(com + 1)))
com++;
break;
#endif
case 'w': // disable specific plugin
if ((na + 1 >= argc) || (argv[na + 1][0] == '-')) {
HTS_PANIC_PRINTF
@@ -1679,7 +1672,7 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
}
break;
//
case 'l': // Accept-language
case 'l':
if ((na + 1 >= argc) || (argv[na + 1][0] == '-')) {
HTS_PANIC_PRINTF
("Option %l needs to be followed by a blank space, and an ISO language code");
@@ -1697,47 +1690,6 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
}
break;
//
case 'a': // Accept
if ((na + 1 >= argc) || (argv[na + 1][0] == '-')) {
HTS_PANIC_PRINTF
("Option %a needs to be followed by a blank space, and a list of formats");
printf("Example: -%%a \"text/html,*/*;q=0.1\"\n");
htsmain_free();
return -1;
} else {
na++;
if (strlen(argv[na]) >= 256) {
HTS_PANIC_PRINTF("Accept list string too long");
htsmain_free();
return -1;
}
StringCopy(opt->accept, argv[na]);
}
break;
//
case 'X': // HTTP header line
if ((na + 1 >= argc) || (argv[na + 1][0] == '-')) {
HTS_PANIC_PRINTF
("Option %X needs to be followed by a blank space, and a raw HTTP header line");
printf("Example: -%%X \"X-Magic: 42\"\n");
htsmain_free();
return -1;
} else {
na++;
if (argv[na][0] == '\0') {
HTS_PANIC_PRINTF("Empty string given");
htsmain_free();
return -1;
} else if (strlen(argv[na]) >= 256) {
HTS_PANIC_PRINTF("Header line string too long");
htsmain_free();
return -1;
}
StringCat(opt->headers, argv[na]);
StringCat(opt->headers, "\r\n"); /* separator */
}
break;
//
case 'F': // footer id
if ((na + 1 >= argc) || (argv[na + 1][0] == '-')) {
HTS_PANIC_PRINTF
@@ -1762,14 +1714,42 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
_DEBUG_HEAD = 1;
break;
case 'O':
#ifdef _WIN32
printf
("Warning option -%%O is no longer supported\n");
("Warning option -%%O has no effect in this system (chroot)\n");
#else
switch_chroot = 1;
#endif
break;
case 'U': // setuid ; removed because insane
HTS_PANIC_PRINTF
("Option %U is no longer supported");
htsmain_free();
return -1;
case 'U': // setuid
if ((na + 1 >= argc) || (argv[na + 1][0] == '-')) {
HTS_PANIC_PRINTF
("Option %U needs to be followed by a blank space, and a username");
printf("Example: -%%U smith\n");
htsmain_free();
return -1;
} else {
na++;
#ifdef _WIN32
printf
("Warning option -%%U has no effect on this system (setuid)\n");
#else
#ifndef HTS_DO_NOT_USE_UID
/* Change the user id and gid */
{
struct passwd *userdef = getpwnam((const char *) argv[na]);
if (userdef) { /* we'll have to switch the user id */
switch_gid = userdef->pw_gid;
switch_uid = userdef->pw_uid;
}
}
#else
printf
("Warning option -%%U has no effect with this compiled version (setuid)\n");
#endif
#endif
}
break;
case 'W': // Wrapper callback
@@ -1877,11 +1857,6 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
}
break;
case 't': /* do not change type (ending) of filenames according to the MIME type */
opt->no_type_change = 1;
if (*(com+1)=='0') { opt->no_type_change = 0; com++; }
break;
default:{
char s[HTS_CDLMAXSIZE + 256];
@@ -1959,7 +1934,7 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
int found = 0;
char *filter = NULL;
cache_back cache;
inthash cache_hashtable = inthash_new(0);
inthash cache_hashtable = inthash_new(HTS_HASH_SIZE);
int backupXFR = htsMemoryFastXfr;
int sendb = 0;
@@ -2199,8 +2174,6 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
return 0;
break;
case '~': /* internal lib test */
HTS_PANIC_PRINTF
("Option #~ is disabled for security reasons");
//Disabled because choke on GCC 4.3 (toni from links2linux.de)
//{
// char thisIsATestYouShouldSeeAnError[12];
@@ -2393,184 +2366,23 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
htsmain_free();
return 0;
break;
case '7': // hashtable selftest: httrack -#7 nb_entries
if (++na < argc) {
char *const snum = strdup(argv[na]);
unsigned long count = 0;
const char *const names[] = {
"", "add", "delete", "dry-add", "dry-del",
"test-exists", "test-not-exist"
};
const struct {
enum {
DO_END,
DO_ADD,
DO_DEL,
DO_DRY_ADD,
DO_DRY_DEL,
TEST_ADD,
TEST_DEL
} type;
size_t modulus;
size_t offset;
} bench[] = {
{ DO_ADD, 4, 0 }, /* add 4/0 */
{ TEST_ADD, 4, 0 }, /* check 4/0 */
{ TEST_DEL, 4, 1 }, /* check 4/1 */
{ TEST_DEL, 4, 2 }, /* check 4/2 */
{ TEST_DEL, 4, 3 }, /* check 4/3 */
{ DO_DRY_DEL, 4, 1 }, /* del 4/1 */
{ DO_DRY_DEL, 4, 2 }, /* del 4/2 */
{ DO_DRY_DEL, 4, 3 }, /* del 4/3 */
{ DO_ADD, 4, 1 }, /* add 4/1 */
{ DO_DRY_ADD, 4, 1 }, /* add 4/1 */
{ TEST_ADD, 4, 0 }, /* check 4/0 */
{ TEST_ADD, 4, 1 }, /* check 4/1 */
{ TEST_DEL, 4, 2 }, /* check 4/2 */
{ TEST_DEL, 4, 3 }, /* check 4/3 */
{ DO_ADD, 4, 2 }, /* add 4/2 */
{ DO_DRY_DEL, 4, 3 }, /* del 4/3 */
{ DO_ADD, 4, 3 }, /* add 4/3 */
{ DO_DEL, 4, 3 }, /* del 4/3 */
{ TEST_ADD, 4, 0 }, /* check 4/0 */
{ TEST_ADD, 4, 1 }, /* check 4/1 */
{ TEST_ADD, 4, 2 }, /* check 4/2 */
{ TEST_DEL, 4, 3 }, /* check 4/3 */
{ DO_DEL, 4, 0 }, /* del 4/0 */
{ DO_DEL, 4, 1 }, /* del 4/1 */
{ DO_DEL, 4, 2 }, /* del 4/2 */
/* empty here */
{ TEST_DEL, 1, 0 }, /* check */
{ DO_ADD, 4, 0 }, /* add 4/0 */
{ DO_ADD, 4, 1 }, /* add 4/1 */
{ DO_ADD, 4, 2 }, /* add 4/2 */
{ DO_DEL, 42, 0 }, /* add 42/0 */
{ TEST_DEL, 42, 0 }, /* check 42/0 */
{ TEST_ADD, 42, 2 }, /* check 42/2 */
{ DO_END }
};
char *buff = NULL;
const char **strings = NULL;
/* produce key #i */
#define FMT() \
char buffer[256]; \
const char *name; \
const long expected = (long) i * 1664525 + 1013904223; \
do { \
if (strings == NULL) { \
snprintf(buffer, sizeof(buffer), \
"http://www.example.com/website/sample/for/hashtable/" \
"%ld/index.html?foo=%ld&bar", \
(long) i, (long) (expected)); \
name = buffer; \
} else { \
name = strings[i]; \
} \
} while(0)
/* produce random patterns, or read from a file */
if (sscanf(snum, "%lu", &count) != 1) {
const off_t size = fsize(snum);
FILE *fp = fopen(snum, "rb");
if (fp != NULL) {
buff = malloc(size);
if (buff != NULL && fread(buff, 1, size, fp) == size) {
size_t capa = 0;
size_t i, last;
for(i = 0, last = 0, count = 0 ; i < size ; i++) {
if (buff[i] == 10 || buff[i] == 0) {
buff[i] = '\0';
if (capa == count) {
if (capa == 0) {
capa = 16;
} else {
capa <<= 1;
}
strings = realloc(strings, capa*sizeof(char*));
}
strings[count++] = &buff[last];
last = i + 1;
}
}
}
fclose(fp);
}
}
/* successfully read */
if (count > 0) {
inthash hashtable = inthash_new(0);
size_t loop;
for(loop = 0 ; bench[loop].type != DO_END ; loop++) {
size_t i;
for(i = bench[loop].offset ; i < (size_t) count
; i += bench[loop].modulus) {
int result;
FMT();
if (bench[loop].type == DO_ADD
|| bench[loop].type == DO_DRY_ADD) {
result = inthash_write(hashtable, name, (uintptr_t) expected);
/* revert logic */
if (bench[loop].type == DO_DRY_ADD) {
result = result ? 0 : 1;
}
}
else if (bench[loop].type == DO_DEL
|| bench[loop].type == DO_DRY_DEL) {
result = inthash_remove(hashtable, name);
/* revert logic */
if (bench[loop].type == DO_DRY_DEL) {
result = result ? 0 : 1;
}
}
else if (bench[loop].type == TEST_ADD
|| bench[loop].type == TEST_DEL) {
intptr_t value = -1;
result = inthash_readptr(hashtable, name, &value);
if (bench[loop].type == TEST_ADD && result
&& value != expected) {
fprintf(stderr, "value failed for %s (expected %ld, got %ld)\n",
name, (long) expected, (long) value);
exit(EXIT_FAILURE);
}
/* revert logic */
if (bench[loop].type == TEST_DEL) {
result = result ? 0 : 1;
}
}
if (!result) {
fprintf(stderr, "failed %s{%d/+%d} test on loop %ld"
" at offset %ld for %s\n",
names[bench[loop].type],
(int) bench[loop].modulus,
(int) bench[loop].offset,
(long) loop, (long) i, name);
exit(EXIT_FAILURE);
}
}
}
inthash_delete(&hashtable);
fprintf(stderr, "all hashtable tests were successful!\n");
} else {
fprintf(stderr, "Malformed number");
exit(EXIT_FAILURE);
}
#undef FMT
case '!':
if (na + 1 >= argc) {
HTS_PANIC_PRINTF
("Option #! needs to be followed by a commandline");
printf("Example: '-#!' 'echo hello'\n");
htsmain_free();
return -1;
} else {
fprintf(stderr,
"Option #7 needs to be followed by a number");
exit(EXIT_FAILURE);
int code;
if ((code = system(argv[na + 1])) != 0) {
fprintf(stderr, "process returned error code %d\n", code);
}
}
htsmain_free();
return 0;
break;
case '!':
HTS_PANIC_PRINTF
("Option #! is disabled for security reasons");
htsmain_free();
return -1;
break;
case 'd':
opt->parsedebug = 1;
break;
@@ -2581,12 +2393,6 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
return 0;
break;
#ifdef HTS_CRASH_TEST
case 'c': /* crash test */
do_crash();
break;
#endif
default:
printf("Internal option %c not recognized\n", *com);
break;
@@ -2713,14 +2519,80 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
#ifdef _WIN32
#else
#ifndef HTS_DO_NOT_USE_UID
/* Check we do not run as r00t */
/* Chroot - xxc */
if (switch_chroot) {
uid_t userid = getuid();
//struct passwd* userdef=getpwuid(userid);
//if (userdef) {
if (!userid) {
//if (strcmp(userdef->pw_name,"root")==0) {
char BIGSTK rpath[1024];
//printf("html=%s log=%s\n",StringBuff(opt->path_html),StringBuff(opt->path_log)); // xxc
if ((StringBuff(opt->path_html)[0]) && (StringBuff(opt->path_log)[0])) {
const char *a = StringBuff(opt->path_html), *b =
StringBuff(opt->path_log), *c = NULL, *d = NULL;
c = a;
d = b;
while((*a) && (*a == *b)) {
if (*a == '/') {
c = a;
d = b;
}
a++;
b++;
}
rpath[0] = '\0';
if (c != StringBuff(opt->path_html)) {
if (StringBuff(opt->path_html)[0] != '/')
strcatbuff(rpath, "./");
strncatbuff(rpath, StringBuff(opt->path_html),
(int) (c - StringBuff(opt->path_html)));
}
StringCopyOverlapped(opt->path_html, c);
StringCopyOverlapped(opt->path_log, d);
} else {
strcpybuff(rpath, "./");
StringCopy(opt->path_html, "/");
StringCopy(opt->path_log, "/");
}
if (rpath[0]) {
printf("[changing root path to %s (path_data=%s,path_log=%s)]\n", rpath,
StringBuff(opt->path_html), StringBuff(opt->path_log));
if (chroot(rpath)) {
printf("ERROR! Can not chroot to %s!\n", rpath);
return -1;
}
if (chdir("/")) { /* new root */
printf("ERROR! Can not chdir to %s!\n", rpath);
return -1;
}
} else
printf("WARNING: chroot not possible with these paths\n");
}
//}
}
/* Setuid */
if (switch_uid >= 0) {
printf("[setting user/group to %d/%d]\n", switch_uid, switch_gid);
if (setgid(switch_gid))
printf("WARNING! Can not setgid to %d!\n", switch_gid);
if (setuid(switch_uid))
printf("WARNING! Can not setuid to %d!\n", switch_uid);
}
/* Final check */
{
uid_t userid = getuid();
if (userid == 0) { /* running as r00t */
if (!userid) { /* running as r00t */
printf("WARNING! You are running this program as root!\n");
printf
("It might be a good idea to run as a different user\n");
("It might be a good idea to use the -%%U option to change the userid:\n");
printf("Example: -%%U smith\n\n");
}
}
#endif

View File

@@ -49,9 +49,11 @@ Please visit our Website: http://www.httrack.com
#ifdef _WIN32
#ifndef __cplusplus
// DOS
#ifndef _WIN32_WCE
#include <process.h> /* _beginthread, _endthread */
#endif
#endif
#endif
// ftp mode passif
// #if HTS_INET6==0

View File

@@ -36,14 +36,24 @@ Please visit our Website: http://www.httrack.com
#define HTTRACK_GLOBAL_DEFH
// Version (also check external version information)
#define HTTRACK_VERSION "3.48-3"
#define HTTRACK_VERSIONID "3.48.3"
#define HTTRACK_VERSION "3.47-27"
#define HTTRACK_VERSIONID "3.47.27"
#define HTTRACK_AFF_VERSION "3.x"
#define HTTRACK_LIB_VERSION "2.0"
#ifndef HTS_NOINCLUDES
#ifndef _WIN32_WCE
#include <stdio.h>
#include <stdlib.h>
#else
#include <stdio.h>
#include <stdlib.h>
#ifdef HTS_CECOMPAT
#include "cecompat.h"
#else
#include "celib.h"
#endif
#endif
#endif
// Définition plate-forme
@@ -60,6 +70,9 @@ Please visit our Website: http://www.httrack.com
// config.h
#ifdef _WIN32
// WIN32
#ifndef _WIN32_WCE
/*
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TYPES_H 1
@@ -78,6 +91,39 @@ Please visit our Website: http://www.httrack.com
#else
// Win32CE
//#pragma runtime_checks( "s", restore )
#define HTS_SPARE_MEMORY 1
#define HTS_ALIGN 8
#define BIGSTK static
#undef DLLIB // LoadLibrary(libssl) crashes
#define NOSTRDEBUG 1
#undef HTS_MAKE_KEYWORD_INDEX
#ifdef HTS_CECOMPAT
#define HTS_DO_NOT_USE_FTIME 1
/*
#undef HAVE_SYS_STAT_H
#undef HAVE_SYS_TYPES_H
*/
#else
#undef HTS_DO_NOT_USE_FTIME
/*
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TYPES_H 1
*/
#endif
#define HTS_DLOPEN 0
#undef HTS_INET6
#ifndef S_ISREG
#define S_ISREG(m) ((m) & _S_IFREG)
#endif
#endif
#else
#include "config.h"
#ifndef FTIME
@@ -151,6 +197,11 @@ Please visit our Website: http://www.httrack.com
#define HTS_USEOPENSSL 1
#endif
// utiliser mms://?
#ifndef HTS_USEMMS
#define HTS_USEMMS 1
#endif
#ifndef HTS_DLOPEN
#define HTS_DLOPEN 1
#endif
@@ -194,11 +245,15 @@ Please visit our Website: http://www.httrack.com
#endif
#if HTS_SPARE_MEMORY==0
/* Gestion des tables de hashage */
#define HTS_HASH_SIZE 20147
/* Taille max d'une URL */
#define HTS_URLMAXSIZE 1024
/* Taille max ligne de commande (>=HTS_URLMAXSIZE*2) */
#define HTS_CDLMAXSIZE 1024
#else
/* Gestion des tables de hashage */
#define HTS_HASH_SIZE 1023
/* Taille max d'une URL */
#define HTS_URLMAXSIZE 256
/* Taille max ligne de commande (>=HTS_URLMAXSIZE*2) */
@@ -227,8 +282,8 @@ Please visit our Website: http://www.httrack.com
#define maximum(A,B) ( (A) > (B) ? (A) : (B) )
#define minimum(A,B) ( (A) < (B) ? (A) : (B) )
/* chaine no empty ? (and not null) */
#define strnotempty(A) (((A) != NULL && (A)[0] != '\0'))
/* chaine vide? */
#define strnotempty(A) (((A)[0]!='\0') ? 1 : 0)
/* optimisation inline si possible */
#ifdef __cplusplus
@@ -271,10 +326,9 @@ typedef __int64 LLint;
typedef __int64 TStamp;
#define LLintP "%I64d"
#elif (defined(_LP64) || defined(__x86_64__) \
|| defined(__powerpc64__) || defined(__64BIT__))
typedef long int LLint;
typedef long int TStamp;
#elif (defined(__x86_64__) || defined(_LP64) || defined(__64BIT__))
typedef unsigned long int LLint;
typedef unsigned long int TStamp;
#define LLintP "%ld"
#else

View File

@@ -42,7 +42,6 @@ Please visit our Website: http://www.httrack.com
#include "htsglobal.h"
#include "htsmd5.h"
#include "htscore.h"
#include "htsinthash.h"
/* END specific definitions */
/* Specific macros */
@@ -56,211 +55,267 @@ Please visit our Website: http://www.httrack.com
// GESTION DES TABLES DE HACHAGE
// Méthode à 2 clés (adr+fil), 2e cle facultative
// hash[no_enregistrement][pos]->hash est un index dans le tableau général liens
// #define HTS_HASH_SIZE 8191 (premier si possible!)
// type: numero enregistrement - 0 est case insensitive (sav) 1 (adr+fil) 2 (former_adr+former_fil)
// recherche dans la table selon nom1,nom2 et le no d'enregistrement
/* Key free handler (NOOP) ; addresses are kept */
static void key_freehandler(void *arg, void *value) {
}
/* Key strdup (pointer copy) */
static char* key_duphandler(void *arg, const char *name) {
union {
const char *roname;
char *name;
} u;
u.roname = name;
return u.name;
}
/* Key sav hashes are using case-insensitive version */
static inthash_keys key_sav_hashes(void *arg, const char *value) {
hash_struct *const hash = (hash_struct*) arg;
convtolower(hash->catbuff, value);
return inthash_hash_value(hash->catbuff);
}
/* Key sav comparison is case-insensitive */
static int key_sav_equals(void *arg, const char *a, const char *b) {
return strcasecmp(a, b) == 0;
}
/* Pseudo-key (lien_url structure) hash function */
static inthash_keys key_adrfil_hashes_generic(void *arg, const char *value_,
const int former) {
hash_struct *const hash = (hash_struct*) arg;
const lien_url*const lien = (lien_url*) value_;
const char *const adr = !former ? lien->adr : lien->former_adr;
const char *const fil = !former ? lien->fil : lien->former_fil;
const char *const adr_norm = adr != NULL ?
( hash->normalized ? jump_normalized(adr) : jump_identification(adr) )
: NULL;
// copy address
assertf(adr_norm != NULL);
strcpy(hash->normfil, adr_norm);
// copy link
assertf(fil != NULL);
if (hash->normalized) {
fil_normalized(fil, &hash->normfil[strlen(hash->normfil)]);
} else {
strcpy(&hash->normfil[strlen(hash->normfil)], fil);
}
// hash
return inthash_hash_value(hash->normfil);
}
/* Pseudo-key (lien_url structure) comparison function */
static int key_adrfil_equals_generic(void *arg, const char *a_, const char *b_,
const int former) {
hash_struct *const hash = (hash_struct*) arg;
const int normalized = hash->normalized;
const lien_url*const a = (lien_url*) a_;
const lien_url*const b = (lien_url*) b_;
const char *const a_adr = !former ? a->adr : a->former_adr;
const char *const b_adr = !former ? b->adr : b->former_adr;
const char *const a_fil = !former ? a->fil : a->former_fil;
const char *const b_fil = !former ? b->fil : b->former_fil;
const char *ja;
const char *jb;
// safety
assertf(a_adr != NULL);
assertf(b_adr != NULL);
assertf(a_fil != NULL);
assertf(b_fil != NULL);
// skip scheme and authentication to the domain (possibly without www.)
ja = normalized ? jump_normalized(a_adr) : jump_identification(a_adr);
jb = normalized ? jump_normalized(b_adr) : jump_identification(b_adr);
assertf(ja != NULL);
assertf(jb != NULL);
if (strcasecmp(ja, jb) != 0) {
return 0;
}
// now compare pathes
if (normalized) {
fil_normalized(a_fil, hash->normfil);
fil_normalized(b_fil, hash->normfil2);
return strcmp(hash->normfil, hash->normfil2) == 0;
} else {
return strcmp(a_fil, b_fil) == 0;
}
}
/* "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);
}
/* "adr"/"fil" lien_url structure members comparison function */
static int key_adrfil_equals(void *arg, const char *a, const char *b) {
return key_adrfil_equals_generic(arg, a, b, 0);
}
/* "former_adr"/"former_fil" lien_url structure members hashing function */
static inthash_keys key_former_adrfil_hashes(void *arg, const char *value_) {
return key_adrfil_hashes_generic(arg, value_, 1);
}
/* "former_adr"/"former_fil" lien_url structure members comparison function */
static int key_former_adrfil_equals(void *arg, const char *a, const char *b) {
return key_adrfil_equals_generic(arg, a, b, 1);
}
void hash_init(hash_struct * hash, int normalized) {
hash->sav = inthash_new(0);
hash->adrfil = inthash_new(0);
hash->former_adrfil = inthash_new(0);
hash->normalized = normalized;
/* Case-insensitive comparison ; keys are direct char* filenames */
inthash_value_set_key_handler(hash->sav,
key_duphandler,
key_freehandler,
key_sav_hashes,
key_sav_equals,
hash);
/* URL-style comparison ; keys are lien_url structure pointers casted
to char* */
inthash_value_set_key_handler(hash->adrfil,
key_duphandler,
key_freehandler,
key_adrfil_hashes,
key_adrfil_equals,
hash);
inthash_value_set_key_handler(hash->former_adrfil,
key_duphandler,
key_freehandler,
key_former_adrfil_hashes,
key_former_adrfil_equals,
hash);
}
void hash_free(hash_struct *hash) {
if (hash != NULL) {
inthash_delete(&hash->sav);
inthash_delete(&hash->adrfil);
inthash_delete(&hash->former_adrfil);
}
}
// retour: position ou -1 si non trouvé
int hash_read(const hash_struct * hash, const char *nom1, const char *nom2,
hash_struct_type type) {
intptr_t intvalue;
lien_url lien;
int type, int normalized) {
char BIGSTK normfil_[HTS_URLMAXSIZE * 2];
char catbuff[CATBUFF_SIZE];
const char *normfil;
const char *normadr;
unsigned int cle;
int pos;
/* read */
switch(type) {
case HASH_STRUCT_FILENAME:
if (inthash_read(hash->sav, nom1, &intvalue)) {
return (int) intvalue;
} else {
return -1;
// calculer la clé de recherche, non modulée
if (type)
cle = hash_cle(nom1, nom2);
else
cle = hash_cle(convtolower(catbuff, nom1), nom2); // case insensitive
// la position se calcule en modulant
pos = (int) (cle % HTS_HASH_SIZE);
// entrée trouvée?
if (hash->hash[type][pos] >= 0) { // un ou plusieurs enregistrement(s) avec une telle clé existe..
// tester table de raccourcis (hash)
// pos est maintenant la position recherchée dans liens
pos = hash->hash[type][pos];
while(pos >= 0) { // parcourir la chaine
switch (type) {
case 0: // sav
if (strfield2(nom1, hash->liens[pos]->sav)) { // case insensitive
#if DEBUG_HASH==2
printf("hash: found shortcut at %d\n", pos);
#endif
return pos;
}
break;
case 1: // adr+fil
{
if (!normalized)
normfil = hash->liens[pos]->fil;
else
normfil = fil_normalized(hash->liens[pos]->fil, normfil_);
if (!normalized)
normadr = jump_identification(hash->liens[pos]->adr);
else
normadr = jump_normalized(hash->liens[pos]->adr);
if ((strfield2(nom1, normadr) != 0) && (strcmp(nom2, normfil) == 0)) {
#if DEBUG_HASH==2
printf("hash: found shortcut at %d\n", pos);
#endif
return pos;
}
}
break;
case 2: // former_adr+former_fil
{
if (hash->liens[pos]->former_adr) {
if (!normalized)
normfil = hash->liens[pos]->former_fil;
else
normfil = fil_normalized(hash->liens[pos]->former_fil, normfil_);
if (!normalized)
normadr = jump_identification(hash->liens[pos]->former_adr);
else
normadr = jump_normalized(hash->liens[pos]->former_adr);
if ((strfield2(nom1, normadr) != 0) && (strcmp(nom2, normfil) == 0)) {
#if DEBUG_HASH==2
printf("hash: found shortcut at %d\n", pos);
#endif
return pos;
}
}
}
break;
}
// calculer prochaine position dans la chaine
{
int old = pos;
pos = hash->liens[pos]->hash_next[type]; // sinon prochain dans la chaine
if (old == pos)
pos = -1; // erreur de bouclage (ne devrait pas arriver)
}
}
break;
case HASH_STRUCT_ADR_PATH:
memset(&lien, 0, sizeof(lien));
lien.adr = key_duphandler(NULL, nom1);
lien.fil = key_duphandler(NULL, nom2);
if (inthash_read(hash->adrfil, (char*) &lien, &intvalue)) {
return (int) intvalue;
} else {
return -1;
}
break;
case HASH_STRUCT_ORIGINAL_ADR_PATH:
memset(&lien, 0, sizeof(lien));
lien.former_adr = key_duphandler(NULL, nom1);
lien.former_fil = key_duphandler(NULL, nom2);
if (inthash_read(hash->former_adrfil, (char*) &lien, &intvalue)) {
return (int) intvalue;
} else {
return -1;
}
break;
default:
assertf(! "unexpected case");
return -1;
break;
// Ok va falloir chercher alors..
/*pos=hash->max_lien; // commencer à max_lien
switch (type) {
case 0: // sav
while(pos>=0) {
if (hash->liens[pos]->hash_sav == cle ) {
if (strcmp(nom1,hash->liens[pos]->sav)==0) {
hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos; // noter plus récent dans shortcut table
#if DEBUG_HASH==2
printf("hash: found long search at %d\n",pos);
#endif
return pos;
}
}
pos--;
}
break;
case 1: // adr+fil
while(pos>=0) {
if (hash->liens[pos]->hash_adrfil == cle ) {
if ((strcmp(nom1,hash->liens[pos]->adr)==0) && (strcmp(nom2,hash->liens[pos]->fil)==0)) {
hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos; // noter plus récent dans shortcut table
#if DEBUG_HASH==2
printf("hash: found long search at %d\n",pos);
#endif
return pos;
}
}
pos--;
}
break;
case 2: // former_adr+former_fil
while(pos>=0) {
if (hash->liens[pos]->hash_fadrfil == cle ) {
if (hash->liens[pos]->former_adr)
if ((strcmp(nom1,hash->liens[pos]->former_adr)==0) && (strcmp(nom2,hash->liens[pos]->former_fil)==0)) {
hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos; // noter plus récent dans shortcut table
#if DEBUG_HASH==2
printf("hash: found long search at %d\n",pos);
#endif
return pos;
}
}
pos--;
}
} */
#if DEBUG_HASH==1
printf("hash: not found after test %s%s\n", nom1, nom2);
#endif
return -1; // non trouvé
} else {
#if DEBUG_HASH==2
printf("hash: not found %s%s\n", nom1, nom2);
#endif
return -1; // non trouvé : clé non entrée (même une fois)
}
}
// enregistrement lien lpos dans les 3 tables hash1..3
void hash_write(hash_struct * hash, int lpos) {
/* first entry: destination filename (lowercased) */
inthash_write(hash->sav, hash->liens[lpos]->sav, lpos);
void hash_write(hash_struct * hash, int lpos, int normalized) {
char BIGSTK normfil_[HTS_URLMAXSIZE * 2];
char catbuff[CATBUFF_SIZE];
const char *normfil;
unsigned int cle;
int pos;
int *ptr;
/* second entry: URL address and path */
inthash_write(hash->adrfil, (char*) hash->liens[lpos], lpos);
/* third entry: URL address and path before redirect */
if (hash->liens[lpos]->former_adr) { // former_adr existe?
inthash_write(hash->former_adrfil, (char*) hash->liens[lpos], lpos);
//
if (hash->liens[lpos]) { // on sait jamais..
hash->max_lien = max(hash->max_lien, lpos);
#if DEBUG_HASH
hashnumber = hash->max_lien;
#endif
// élément actuel sur -1 (fin de chaine)
hash->liens[lpos]->hash_next[0] = hash->liens[lpos]->hash_next[1] =
hash->liens[lpos]->hash_next[2] = -1;
//
cle = hash_cle(convtolower(catbuff, hash->liens[lpos]->sav), ""); // CASE INSENSITIVE
pos = (int) (cle % HTS_HASH_SIZE);
ptr = hash_calc_chaine(hash, 0, pos); // calculer adresse chaine
*ptr = lpos; // noter dernier enregistré
#if DEBUG_HASH==3
printf("[%d", pos);
#endif
//
if (!normalized)
normfil = hash->liens[lpos]->fil;
else
normfil = fil_normalized(hash->liens[lpos]->fil, normfil_);
if (!normalized)
cle = hash_cle(jump_identification(hash->liens[lpos]->adr), normfil);
else
cle = hash_cle(jump_normalized(hash->liens[lpos]->adr), normfil);
pos = (int) (cle % HTS_HASH_SIZE);
ptr = hash_calc_chaine(hash, 1, pos); // calculer adresse chaine
*ptr = lpos; // noter dernier enregistré
#if DEBUG_HASH==3
printf(",%d", pos);
#endif
//
if (hash->liens[lpos]->former_adr) { // former_adr existe?
if (!normalized)
normfil = hash->liens[lpos]->former_fil;
else
normfil = fil_normalized(hash->liens[lpos]->former_fil, normfil_);
if (!normalized)
cle =
hash_cle(jump_identification(hash->liens[lpos]->former_adr), normfil);
else
cle = hash_cle(jump_normalized(hash->liens[lpos]->former_adr), normfil);
pos = (int) (cle % HTS_HASH_SIZE);
ptr = hash_calc_chaine(hash, 2, pos); // calculer adresse chaine
*ptr = lpos; // noter dernier enregistré
#if DEBUG_HASH==3
printf(",%d", pos);
#endif
}
#if DEBUG_HASH==3
printf("] ");
fflush(stdout);
#endif
}
#if DEBUT_HASH
else {
printf("* hash_write=0!!\n");
abortLogFmt("unexpected error in hash_write (pos=%d)" _pos);
abort();
}
#endif
//
}
// calcul clé
// il n'y a pas de formule de hashage universelle, celle-ci semble acceptable..
unsigned long int hash_cle(const char *nom1, const char *nom2) {
/*
unsigned int sum=0;
int i=0;
while(*nom1) {
sum += 1;
sum += (unsigned int) *(nom1);
sum *= (unsigned int) *(nom1++);
sum += (unsigned int) i;
i++;
}
while(*nom2) {
sum += 1;
sum += (unsigned int) *(nom2);
sum *= (unsigned int) *(nom2++);
sum += (unsigned int) i;
i++;
}
*/
return md5sum32(nom1)
+ md5sum32(nom2);
}
// calcul de la position finale dans la chaine des elements ayant la même clé
int *hash_calc_chaine(hash_struct * hash, int type, int pos) {
#if DEBUG_HASH
int count = 0;
#endif
if (hash->hash[type][pos] == -1)
return &(hash->hash[type][pos]); // premier élément dans la chaine
pos = hash->hash[type][pos];
while(hash->liens[pos]->hash_next[type] != -1) {
pos = hash->liens[pos]->hash_next[type];
#if DEBUG_HASH
count++;
#endif
}
#if DEBUG_HASH
count++;
longest_hash[type] = max(longest_hash[type], count);
#endif
return &(hash->liens[pos]->hash_next[type]);
}
// FIN GESTION DES TABLES DE HACHAGE

View File

@@ -43,20 +43,11 @@ Please visit our Website: http://www.httrack.com
typedef struct hash_struct hash_struct;
#endif
/** Type of hash. **/
typedef enum hash_struct_type {
HASH_STRUCT_FILENAME = 0,
HASH_STRUCT_ADR_PATH,
HASH_STRUCT_ORIGINAL_ADR_PATH
} hash_struct_type;
// tables de hachage
void hash_init(hash_struct *hash, int normalized);
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);
int *hash_calc_chaine(hash_struct * hash, hash_struct_type type, int pos);
int type, int normalized);
void hash_write(hash_struct * hash, int lpos, int normalized);
int *hash_calc_chaine(hash_struct * hash, int type, int pos);
unsigned long int hash_cle(const char *nom1, const char *nom2);
#endif

View File

@@ -485,6 +485,10 @@ void help(char *app, int more) {
infomsg(" %cN maximum number of connections/seconds (*%c10)");
infomsg
(" GN pause transfer if N bytes reached, and wait until lock file is deleted");
#if HTS_USEMMS
infomsg
(" %mN maximum mms stream download time in seconds (60=1 minute, 3600=1 hour)");
#endif
infomsg("");
infomsg("Flow control:");
infomsg(" cN number of multiple connections (*c8)");
@@ -568,8 +572,6 @@ void help(char *app, int more) {
infomsg
(" %F footer string in Html code (-%F \"Mirrored [from host %s [file %s [at %s]]]\"");
infomsg(" %l preffered language (-%l \"fr, en, jp, *\"");
infomsg(" %a accepted formats (-%l \"text/html,image/png,image/jpeg,image/gif;q=0.9,*/*;q=0.1\"");
infomsg(" %X additional HTTP header line (-%X \"X-Magic: 42\"");
infomsg("");
infomsg("Log, index, cache");
infomsg

View File

@@ -119,12 +119,14 @@ int hts_primindex_words = 0;
*/
void index_init(const char *indexpath) {
#if HTS_MAKE_KEYWORD_INDEX
#ifndef _WIN32_WCE
/* remove(concat(indexpath,"index.txt")); */
hts_index_init = 1;
hts_primindex_size = 0;
hts_primindex_words = 0;
fp_tmpproject = tmpfile();
#endif
#endif
}
/*
@@ -143,7 +145,7 @@ int index_keyword(const char *html_data, LLint size, const char *mime,
int i = 0;
//
//int WordIndexSize = 1024;
int WordIndexSize = 1024;
inthash WordIndexHash = NULL;
FILE *tmpfp = NULL;
@@ -172,7 +174,11 @@ int index_keyword(const char *html_data, LLint size, const char *mime,
// FIXME - temporary fix for image/svg+xml (svg)
// "IN XML" (html like, in fact :) )
else if ((strfield2(mime, "image/svg+xml"))
|| (strfield2(mime, "image/svg-xml"))) {
|| (strfield2(mime, "image/svg-xml"))
#if HTS_USEMMS
|| strfield2(mime, "video/x-ms-asf")
#endif
) {
inscript = 0;
} else if ((strfield2(mime, "application/x-javascript"))
|| (strfield2(mime, "text/css"))
@@ -190,7 +196,7 @@ int index_keyword(const char *html_data, LLint size, const char *mime,
// Create hash structure
// Hash tables rulez da world!
WordIndexHash = inthash_new(0);
WordIndexHash = inthash_new(WordIndexSize);
if (!WordIndexHash)
return 0;

File diff suppressed because it is too large Load Diff

View File

@@ -31,28 +31,7 @@ Please visit our Website: http://www.httrack.com
/* Author: Xavier Roche */
/* ------------------------------------------------------------ */
/**
* Library notes:
* This small hashtable library provides key/value hashtable, with a string
* key, and integer/pointer value (with an associated optional allocator)
* It features O(1) average insertion, O(1) lookup, and O(1) delete.
*
* Implementation notes:
* Implementation is auto-rehashable, and uses cuckoo hashing of size 2**n
* with a MD5 or FNV-1 hash function, with one additional auxiliary hash
* function.
* It also uses a small stash area to handle rare cases of collisions.
* Enumeration of all key/values is possible, deletion is also possible, but
* currently without any auto-shrinking (ie. table will never shrink).
* Overall, two main blocks are allocated: one for the items, and one for
* the keys (pool).
*
* References:
* Cuckoo Hashing http://en.wikipedia.org/wiki/Cuckoo_hashing
* Cuckoo Stash http://research.microsoft.com/pubs/73856/stash-full.9-30.pdf
* FNV http://www.isthe.com/chongo/tech/comp/fnv/
* MD5 http://en.wikipedia.org/wiki/MD5
**/
// inthash -- simple hash table, using a key (char[]) and a value (uintptr_t)
#ifndef HTSINTHASH_DEFH
#define HTSINTHASH_DEFH
@@ -60,8 +39,6 @@ Please visit our Website: http://www.httrack.com
/* Includes */
#ifdef _WIN32
#include <stddef.h>
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#elif (defined(SOLARIS) || defined(sun) || defined(HAVE_INTTYPES_H) \
|| defined(BSD) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD_kernel__))
#include <inttypes.h>
@@ -69,246 +46,94 @@ typedef unsigned __int64 uint64_t;
#include <stdint.h>
#endif
/** Value. **/
// value
typedef union inthash_value {
/** Integer value. **/
intptr_t intg;
/** Unsigned integer value. **/
uintptr_t uintg;
/** Pointer value. **/
void *ptr;
uintptr_t intg; /* integer value */
void *ptr; /* ptr value */
} inthash_value;
/** NULL Value. **/
#define INTHASH_VALUE_NULL { 0 }
#ifndef HTS_DEF_FWSTRUCT_inthash_item
#define HTS_DEF_FWSTRUCT_inthash_item
typedef struct inthash_item inthash_item;
// simple hash table for other routines
#ifndef HTS_DEF_FWSTRUCT_inthash_chain
#define HTS_DEF_FWSTRUCT_inthash_chain
typedef struct inthash_chain inthash_chain;
#endif
/** Hash key (32-bit) **/
typedef uint32_t inthash_key;
/** Pair of hashes **/
typedef struct inthash_keys {
inthash_key hash1;
inthash_key hash2;
} inthash_keys;
/** NULL pair of hashes. **/
#define INTHASH_KEYS_NULL { 0, 0 }
/** Item holding a value. **/
struct inthash_item {
/** Key. **/
char *name;
/** Value. **/
inthash_value value;
/** Hashes of the key. **/
inthash_keys hashes;
struct inthash_chain {
char *name; /* key (name) */
inthash_value value; /* value */
struct inthash_chain *next; /* next element */
};
/** Alias for legacy code. **/
typedef inthash_item inthash_chain;
typedef void (*t_inthash_freehandler) (void *value);
/** Value free handler **/
typedef void (*t_inthash_freehandler) (void *arg, void *value);
/** Name dup handler. **/
typedef char* (*t_inthash_duphandler) (void *arg, const char *name);
/** Hash computation handler. **/
typedef inthash_keys (*t_inthash_hasheshandler)(void *arg, const char *value);
/**
* Value comparison handler (returns non-zero value if strings are equal).
**/
typedef int (*t_inthash_cmphandler)(void *arg, const char *a, const char *b);
/** Hashtable (opaque structure). **/
/* inthash structure */
#ifndef HTS_DEF_FWSTRUCT_struct_inthash
#define HTS_DEF_FWSTRUCT_struct_inthash
typedef struct struct_inthash struct_inthash, *inthash;
#endif
struct struct_inthash {
inthash_chain **hash;
unsigned int nitems;
t_inthash_freehandler free_handler;
unsigned int hash_size;
unsigned short flag_valueismalloc;
};
/** Hashtable enumeration (opaque structure). **/
// enumeration
#ifndef HTS_DEF_FWSTRUCT_struct_inthash_enum
#define HTS_DEF_FWSTRUCT_struct_inthash_enum
typedef struct struct_inthash_enum struct_inthash_enum;
#endif
/** Enumeration. **/
struct struct_inthash_enum {
inthash table;
size_t index;
int index;
inthash_chain *item;
};
/* Library internal definictions */
#ifdef HTS_INTERNAL_BYTECODE
/**
* Create a new hashtable, with initial bucket size of 'size'.
* If size is 0, use the default minimal bucket size.
* Return a non-NULL pointer upon success.
**/
inthash inthash_new(size_t size);
// main functions:
/**
* Was the hashtable successfully created ?
* Return non-zero value if the hashtable is valid.
**/
int inthash_created(inthash hashtable);
/* Hash functions: */
inthash inthash_new(int size); /* Create a new hash table */
int inthash_created(inthash hashtable); /* Test if the hash table was successfully created */
unsigned int inthash_nitems(inthash hashtable); /* Number of items */
void inthash_delete(inthash * hashtable); /* Delete an hash table */
void inthash_value_is_malloc(inthash hashtable, int flag); /* Is the 'value' member a value that needs to be free()'ed ? */
void inthash_value_set_free_handler(inthash hashtable, /* value free() handler (default one is 'free') */
t_inthash_freehandler free_handler);
/**
* Delete a hashtable, freeing all entries.
**/
void inthash_delete(inthash * hashtable);
/* */
int inthash_read(inthash hashtable, const char *name, intptr_t * intvalue); /* Read entry from the hash table */
int inthash_readptr(inthash hashtable, const char *name, intptr_t * intvalue); /* Same function, but returns 0 upon null ptr */
int inthash_exists(inthash hashtable, const char *name); /* Is the key existing ? */
/**
* Return the number of items in the hashtable.
**/
size_t inthash_nitems(inthash hashtable);
/**
* Return the memory size taken by the hashtable.
* (This does not take account of the possible memory taken by values)
**/
size_t inthash_memory_size(inthash hashtable);
/**
* If 'flag' is non-zero, calls inthash_value_set_value_handler() with
* default system free() handler function, otherwise, free the value handlers.
**/
void inthash_value_is_malloc(inthash hashtable, int flag);
/**
* Set handlers for values.
* free: this handler will be called when a value is to be removed from
* the hashtable. if NULL, values won't be free'd.
* arg: opaque custom argument to be used by functions.
* Handler(s) MUST NOT be changed once elements have been added.
**/
void inthash_value_set_value_handler(inthash hashtable,
t_inthash_freehandler free,
void *arg);
/**
* Set handlers for keys.
* dup: handler called to duplicate a key. if NULL, the internal pool is used.
* free: handler called to free a key. if NULL, the internal pool is used.
* hash: hashing handler, called to hash a key. if NULL, the default hash
* function is used.
* equals: comparison handler, returning non-zero value when two keys are
* identical. if NULL, the default comparison function is used.
* arg: opaque custom argument to be used by functions.
* Handler(s) MUST NOT be changed once elements have been added.
**/
void inthash_value_set_key_handler(inthash hashtable,
t_inthash_duphandler dup,
t_inthash_freehandler free,
t_inthash_hasheshandler hash,
t_inthash_cmphandler equals,
void *arg);
/**
* Read an integer entry from the hashtable.
* Return non-zero value upon success and sets intvalue.
**/
int inthash_read(inthash hashtable, const char *name, intptr_t * intvalue);
/**
* Same as inthash_read(), but return 0 is the value was zero.
**/
int inthash_readptr(inthash hashtable, const char *name, intptr_t * intvalue);
/**
* Return non-zero value if the given entry exists.
**/
int inthash_exists(inthash hashtable, const char *name);
/**
* Read an entry from the hashtable.
* Return non-zero value upon success and sets value.
**/
/* */
int inthash_read_value(inthash hashtable, const char *name,
inthash_value * value);
/**
* Write an entry to the hashtable.
* Return non-zero value if the entry was added, zero if it was replaced.
**/
int inthash_write_value(inthash hashtable, const char *name,
inthash_value value);
/**
* Read a pointer entry from the hashtable.
* Return non-zero value upon success and sets value.
**/
void inthash_add_value(inthash hashtable, const char *name,
inthash_value value);
/* */
int inthash_read_pvoid(inthash hashtable, const char *name, void **value);
/**
* Write a pointer entry to the hashtable.
* Return non-zero value if the entry was added, zero if it was replaced.
**/
int inthash_write_pvoid(inthash hashtable, const char *name, void *value);
/**
* Alias to inthash_write_pvoid()
**/
void inthash_add_pvoid(inthash hashtable, const char *name, void *value);
/**
* Write an integer entry to the hashtable.
* Return non-zero value if the entry was added, zero if it was replaced.
**/
int inthash_write(inthash hashtable, const char *name, intptr_t value);
/* */
void inthash_add(inthash hashtable, const char *name, intptr_t value); /* Add entry in the hash table */
void *inthash_addblk(inthash hashtable, const char *name, int blksize); /* Add entry in the hash table and set value to a new memory block */
int inthash_write(inthash hashtable, const char *name, intptr_t value); /* Overwrite/add entry in the hash table */
int inthash_inc(inthash hashtable, const char *name); /* Increment entry in the hash table */
int inthash_remove(inthash hashtable, const char *name); /* Remove an entry from the hashtable */
/**
* Alias to inthash_write()
**/
void inthash_add(inthash hashtable, const char *name, intptr_t value);
/**
* Increment an entry value in the hashtable
* (or create a new entry with value 1 if it does not yet exist)
* Return non-zero value if the entry was added, zero if it was changed.
**/
int inthash_inc(inthash hashtable, const char *name);
/**
* Decrement an entry value in the hashtable
* (or create a new entry with value -1 if it does not yet exist)
* Return non-zero value if the entry was added, zero if it was changed.
**/
int inthash_dec(inthash hashtable, const char *name);
/**
* Remove an entry from the hashtable
* Return non-zero value if the entry was removed, zero otherwise.
**/
int inthash_remove(inthash hashtable, const char *name);
/**
* Return a new enumerator.
* Note: deleting entries is safe while enumerating, but adding entries
* lead to undefined enumeration behavior (yet safe).
**/
struct_inthash_enum inthash_enum_new(inthash hashtable);
/**
* Enumerate the next entry.
**/
inthash_item *inthash_enum_next(struct_inthash_enum * e);
/**
* Compute a hash, given a string value.
**/
inthash_keys inthash_hash_value(const char *value);
/* */
struct_inthash_enum inthash_enum_new(inthash hashtable); /* Start a new enumerator */
inthash_chain *inthash_enum_next(struct_inthash_enum * e); /* Fetch an item in the enumerator */
/* End of hash functions: */
#endif
#endif

View File

@@ -446,14 +446,12 @@ static RESP_STRUCT readtable(htsmoduleStruct * str, FILE * fp,
static unsigned short int readshort(FILE * fp) {
unsigned short int valint;
if (fread(&valint, sizeof(valint), 1, fp) == 1) {
if (reverse_endian())
return hts_swap16(valint);
else
return valint;
} else {
return 0;
}
fread(&valint, sizeof(valint), 1, fp);
if (reverse_endian())
return hts_swap16(valint);
else
return valint;
}

View File

@@ -37,6 +37,12 @@ Please visit our Website: http://www.httrack.com
#include "htscore.h"
#ifdef _WIN32_WCE
#ifndef HTS_CECOMPAT
#pragma comment(lib, "celib.lib") //link with celib
#endif
#endif
/* specific definitions */
#include "htsbase.h"
#include "htsnet.h"
@@ -50,7 +56,9 @@ Please visit our Website: http://www.httrack.com
#include "htsencoding.h"
#ifdef _WIN32
#ifndef _WIN32_WCE
#include <direct.h>
#endif
#else
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -65,22 +73,33 @@ Please visit our Website: http://www.httrack.com
#include <string.h>
#include <time.h>
#ifdef __ANDROID__
static long int timezone = 0;
#endif
#include <stdarg.h>
#ifndef _WIN32_WCE
#include <sys/timeb.h>
#include <fcntl.h>
#else
#ifndef HTS_CECOMPAT
#include <sys/timeb.h>
#endif
#endif /* _WIN32_WCE */
// pour utimbuf
#ifdef _WIN32
#ifndef _WIN32_WCE
#include <sys/utime.h>
#else
#ifndef HTS_CECOMPAT
#include <sys/utime.h>
#endif
#endif
#else
#include <utime.h>
#endif /* _WIN32 */
#ifndef _WIN32_WCE
#include <sys/stat.h>
#endif
/* END specific definitions */
// Debugging
@@ -590,6 +609,10 @@ char *antislash(char *catbuff, const char *s) {
}
#endif
#ifdef _WIN32_WCE
char cwd[MAX_PATH + 1] = "";
#endif
// Initialize a htsblk structure
void hts_init_htsblk(htsblk * r) {
memset(r, 0, sizeof(htsblk)); // effacer
@@ -599,6 +622,36 @@ void hts_init_htsblk(htsblk * r) {
r->totalsize = -1;
}
// Récupération d'un fichier http sur le net.
// Renvoie une adresse sur le bloc de mémoire, ou bien
// NULL si un retour.msgeur (buffer retour.msg) est survenue.
//
// Une adresse de structure htsmsg peut être transmise pour
// suivre l'évolution du chargement si le process a été lancé
// en background
htsblk httpget(httrackp * opt, char *url) {
char BIGSTK adr[HTS_URLMAXSIZE * 2]; // adresse
char BIGSTK fil[HTS_URLMAXSIZE * 2]; // chemin
// séparer URL en adresse+chemin
if (ident_url_absolute(url, adr, fil) == -1) {
htsblk retour;
hts_init_htsblk(&retour);
//memset(&retour, 0, sizeof(htsblk)); // effacer
// retour prédéfini: erreur
retour.adr = NULL;
retour.size = 0;
retour.msg[0] = '\0';
retour.statuscode = STATUSCODE_INVALID;
strcpybuff(retour.msg, "Error invalid URL");
return retour;
}
return xhttpget(opt, adr, fil);
}
// ouvre une liaison http, envoie une requète GET et réceptionne le header
// retour: socket
T_SOC http_fopen(httrackp * opt, char *adr, char *fil, htsblk * retour) {
@@ -700,6 +753,8 @@ T_SOC http_xfopen(httrackp * opt, int mode, int treat, int waitconnect,
soc = INVALID_SOCKET;
if (retour->totalsize < 0)
strcpybuff(retour->msg, "Unable to open local file");
else if (retour->totalsize == 0)
strcpybuff(retour->msg, "File empty");
else {
// Note: On passe par un FILE* (plus propre)
//soc=open(fil,O_RDONLY,0); // en lecture seule!
@@ -795,56 +850,17 @@ T_SOC http_xfopen(httrackp * opt, int mode, int treat, int waitconnect,
return soc;
}
/* Buffer printing */
typedef struct buff_struct {
/** Buffer **/
char *buffer;
/** Buffer capacity in bytes **/
size_t capacity;
/** Buffer write position ; MUST point to a valid \0. **/
size_t pos;
} buff_struct;
static void print_buffer(buff_struct*const str, const char *format, ...)
HTS_PRINTF_FUN(2, 3);
/* Prints on a static buffer. asserts in case of overflow. */
static void print_buffer(buff_struct*const str, const char *format, ...) {
size_t result;
va_list args;
size_t remaining;
char *position;
/* Security check. */
assert(str != NULL);
assert(str->pos < str->capacity);
/* Print */
position = &str->buffer[str->pos];
remaining = str->capacity - str->pos;
va_start(args, format);
result = (size_t) vsnprintf(position, remaining, format, args);
va_end(args);
assertf(result < remaining);
/* Increment. */
str->pos += strlen(position);
assert(str->pos < str->capacity);
}
// envoi d'une requète
int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
char *adr, char *fil, char *referer_adr, char *referer_fil,
htsblk * retour) {
char BIGSTK buffer_head_request[8192];
buff_struct bstr = { buffer_head_request, sizeof(buffer_head_request), 0 };
char BIGSTK buff[8192];
//int use_11=0; // HTTP 1.1 utilisé
int direct_url = 0; // ne pas analyser l'url (exemple: ftp://)
char *search_tag = NULL;
// Initialize buffer
buffer_head_request[0] = '\0';
buff[0] = '\0';
// header Date
//strcatbuff(buff,"Date: ");
@@ -871,23 +887,18 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
linput(fp, line, 1000);
if (sscanf(line, "%s %s %s", method, url, protocol) == 3) {
size_t ret;
int ret;
// selon que l'on a ou pas un proxy
if (retour->req.proxy.active) {
print_buffer(&bstr,
"%s http://%s%s %s\r\n", method, adr, url,
if (retour->req.proxy.active)
sprintf(buff, "%s http://%s%s %s\r\n", method, adr, url,
protocol);
} else {
print_buffer(&bstr,
"%s %s %s\r\n", method, url, protocol);
}
else
sprintf(buff, "%s %s %s\r\n", method, url, protocol);
// lire le reste en brut
ret = fread(&bstr.buffer[bstr.pos],
bstr.capacity - bstr.pos, 1, fp);
if ((int) ret < 0) {
ret = fread(buff + strlen(buff), 8000 - strlen(buff), 1, fp);
if (ret < 0) {
return -1;
}
bstr.pos += strlen(&bstr.buffer[bstr.pos]);
}
fclose(fp);
}
@@ -896,17 +907,17 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
}
// Fin postfile
if (bstr.pos == 0) { // PAS POSTFILE
if (strnotempty(buff) == 0) { // PAS POSTFILE
// Type de requète?
if ((search_tag) && (mode == 0)) {
print_buffer(&bstr, "POST ");
strcatbuff(buff, "POST ");
} else if (mode == 0) { // GET
print_buffer(&bstr, "GET ");
strcatbuff(buff, "GET ");
} else { // if (mode==1) {
if (!retour->req.http11) // forcer HTTP/1.0
print_buffer(&bstr, "GET "); // certains serveurs (cgi) buggent avec HEAD
strcatbuff(buff, "GET "); // certains serveurs (cgi) buggent avec HEAD
else
print_buffer(&bstr, "HEAD ");
strcatbuff(buff, "HEAD ");
}
// si on gère un proxy, il faut une Absolute URI: on ajoute avant http://www.adr.dom
@@ -916,21 +927,21 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
printf("Proxy Use: for %s%s proxy %d port %d\n", adr, fil,
retour->req.proxy.name, retour->req.proxy.port);
#endif
print_buffer(&bstr, "http://%s", jump_identification(adr));
strcatbuff(buff, "http://");
strcatbuff(buff, jump_identification(adr));
} else { // ftp:// en proxy http
#if HDEBUG
printf("Proxy Use for ftp: for %s%s proxy %d port %d\n", adr, fil,
retour->req.proxy.name, retour->req.proxy.port);
#endif
direct_url = 1; // ne pas analyser user/pass
print_buffer(&bstr, "%s", adr);
strcatbuff(buff, adr);
}
}
// NOM DU FICHIER
// on slash doit être présent en début, sinon attention aux bad request! (400)
if (*fil != '/')
print_buffer(&bstr, "/");
strcatbuff(buff, "/");
{
char BIGSTK tempo[HTS_URLMAXSIZE * 2];
@@ -940,21 +951,21 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
else
strcpybuff(tempo, fil);
escape_check_url(tempo);
print_buffer(&bstr, "%s", tempo); // avec échappement
strcatbuff(buff, tempo); // avec échappement
}
// protocole
if (!retour->req.http11) { // forcer HTTP/1.0
//use_11=0;
print_buffer(&bstr, " HTTP/1.0\x0d\x0a");
strcatbuff(buff, " HTTP/1.0\x0d\x0a");
} else { // Requète 1.1
//use_11=1;
print_buffer(&bstr, " HTTP/1.1\x0d\x0a");
strcatbuff(buff, " HTTP/1.1\x0d\x0a");
}
/* supplemental data */
if (xsend)
print_buffer(&bstr, "%s", xsend); // éventuelles autres lignes
strcatbuff(buff, xsend); // éventuelles autres lignes
// tester proxy authentication
if (retour->req.proxy.active) {
@@ -970,8 +981,9 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
strcpybuff(user_pass, unescape_http(OPT_GET_BUFF(opt), user_pass));
code64((unsigned char *) user_pass, (int) strlen(user_pass),
(unsigned char *) autorisation, 0);
print_buffer(&bstr, "Proxy-Authorization: Basic %s"H_CRLF,
autorisation);
strcatbuff(buff, "Proxy-Authorization: Basic ");
strcatbuff(buff, autorisation);
strcatbuff(buff, H_CRLF);
#if HDEBUG
printf("Proxy-Authenticate, %s (code: %s)\n", user_pass, autorisation);
#endif
@@ -987,22 +999,30 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
||(strncmp(adr, "https://", 8) == 0) /* or referer AND addresses are https */
)
) { // PAS file://
print_buffer(&bstr, "Referer: http://%s%s"H_CRLF,
jump_identification(referer_adr), referer_fil);
strcatbuff(buff, "Referer: ");
strcatbuff(buff, "http://");
strcatbuff(buff, jump_identification(referer_adr));
strcatbuff(buff, referer_fil);
strcatbuff(buff, H_CRLF);
}
}
// HTTP field: referer
else if (strnotempty(retour->req.referer)) {
print_buffer(&bstr, "Referer: %s"H_CRLF, retour->req.referer);
else if (retour->req.referer[0] != '\0') {
strcatbuff(buff, "Referer: ");
strcatbuff(buff, retour->req.referer);
strcatbuff(buff, H_CRLF);
}
// POST?
if (mode == 0) { // GET!
if (search_tag) {
print_buffer(&bstr, "Content-length: %d" H_CRLF,
char clen[256];
sprintf(clen, "Content-length: %d" H_CRLF,
(int) (strlen
(unescape_http
(OPT_GET_BUFF(opt),
search_tag + strlen(POSTTOK) + 1))));
strcatbuff(buff, clen);
}
}
// gestion cookies?
@@ -1011,77 +1031,93 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
char *b = cookie->data;
int cook = 0;
int max_cookies = 8;
size_t max_size = 2048;
max_size += strlen(buff);
do {
b = cookie_find(b, "", jump_identification(adr), fil); // prochain cookie satisfaisant aux conditions
if (b != NULL) {
if (b) {
max_cookies--;
if (!cook) {
print_buffer(&bstr, "Cookie: $Version=1; ");
strcatbuff(buff, "Cookie: ");
strcatbuff(buff, "$Version=1; ");
cook = 1;
} else
print_buffer(&bstr, "; ");
print_buffer(&bstr, "%s", cookie_get(buffer, b, 5));
print_buffer(&bstr, "=%s", cookie_get(buffer, b, 6));
print_buffer(&bstr, "; $Path=%s", cookie_get(buffer, b, 2));
strcatbuff(buff, "; ");
strcatbuff(buff, cookie_get(buffer, b, 5));
strcatbuff(buff, "=");
strcatbuff(buff, cookie_get(buffer, b, 6));
strcatbuff(buff, "; $Path=");
strcatbuff(buff, cookie_get(buffer, b, 2));
b = cookie_nextfield(b);
}
} while(b != NULL && max_cookies > 0);
} while((b) && (max_cookies > 0) && ((int) strlen(buff) < max_size));
if (cook) { // on a envoyé un (ou plusieurs) cookie?
print_buffer(&bstr, H_CRLF);
strcatbuff(buff, H_CRLF);
#if DEBUG_COOK
printf("Header:\n%s\n", bstr.buffer);
printf("Header:\n%s\n", buff);
#endif
}
}
// gérer le keep-alive (garder socket)
if (retour->req.http11 && !retour->req.nokeepalive) {
print_buffer(&bstr, "Connection: keep-alive" H_CRLF);
strcatbuff(buff, "Connection: Keep-Alive" H_CRLF);
} else {
print_buffer(&bstr, "Connection: close" H_CRLF);
strcatbuff(buff, "Connection: close" H_CRLF);
}
{
char *real_adr = jump_identification(adr);
// Mandatory per RFC2616
//if ((use_11) || (retour->user_agent_send)) { // Pour le 1.1 on utilise un Host:
if (!direct_url) { // pas ftp:// par exemple
print_buffer(&bstr, "Host: %s"H_CRLF, real_adr);
//if (!retour->req.proxy.active) {
strcatbuff(buff, "Host: ");
strcatbuff(buff, real_adr);
strcatbuff(buff, H_CRLF);
//}
}
//}
// HTTP field: from
if (strnotempty(retour->req.from)) { // HTTP from
print_buffer(&bstr, "From: %s" H_CRLF, retour->req.from);
if (retour->req.from[0] != '\0') { // HTTP from
strcatbuff(buff, "From: ");
strcatbuff(buff, retour->req.from);
strcatbuff(buff, H_CRLF);
}
// Présence d'un user-agent?
if (retour->req.user_agent_send
&& strnotempty(retour->req.user_agent)) {
print_buffer(&bstr, "User-Agent: %s" H_CRLF, retour->req.user_agent);
}
if (retour->req.user_agent_send) { // ohh un user-agent
char s[256];
// Accept
if (strnotempty(retour->req.accept)) {
print_buffer(&bstr, "Accept: %s" H_CRLF, retour->req.accept);
}
// HyperTextSeeker/"HTSVERSION
sprintf(s, "User-Agent: %s" H_CRLF, retour->req.user_agent);
strcatbuff(buff, s);
// Accept-language
if (strnotempty(retour->req.lang_iso)) {
print_buffer(&bstr, "Accept-Language: %s"H_CRLF, retour->req.lang_iso);
}
// Compression accepted ?
if (retour->req.http11) {
// pour les serveurs difficiles
strcatbuff(buff, "Accept: " "image/png, image/jpeg, image/pjpeg, image/x-xbitmap, image/svg+xml" /* Accepted */
", " "image/gif;q=0.9" /* also accepted but with lower preference */
", " "*/*;q=0.1" /* also accepted but with even lower preference */
H_CRLF);
if (strnotempty(retour->req.lang_iso)) {
strcatbuff(buff, "Accept-Language: ");
strcatbuff(buff, retour->req.lang_iso);
strcatbuff(buff, H_CRLF);
}
if (retour->req.http11) {
#if HTS_USEZLIB
if ((!retour->req.range_used)
&& (!retour->req.nocompression))
print_buffer(&bstr, "Accept-Encoding: " "gzip" /* gzip if the preffered encoding */
", " "identity;q=0.9" H_CRLF);
else
print_buffer(&bstr, "Accept-Encoding: identity" H_CRLF); /* no compression */
//strcatbuff(buff,"Accept-Encoding: gzip, deflate, compress, identity"H_CRLF);
if ((!retour->req.range_used)
&& (!retour->req.nocompression))
strcatbuff(buff, "Accept-Encoding: " "gzip" /* gzip if the preffered encoding */
", " "identity;q=0.9" H_CRLF);
else
strcatbuff(buff, "Accept-Encoding: identity" H_CRLF); /* no compression */
#else
print_buffer(&bstr, "Accept-Encoding: identity" H_CRLF); /* no compression */
strcatbuff(buff, "Accept-Encoding: identity" H_CRLF); /* no compression */
#endif
}
} else {
strcatbuff(buff, "Accept: */*" H_CRLF); // le minimum
}
/* Authentification */
@@ -1109,25 +1145,23 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
strcpybuff(autorisation, a);
/* On a une autorisation a donner? */
if (strnotempty(autorisation)) {
print_buffer(&bstr, "Authorization: Basic %s"H_CRLF, autorisation);
strcatbuff(buff, "Authorization: Basic ");
strcatbuff(buff, autorisation);
strcatbuff(buff, H_CRLF);
}
}
}
//strcatbuff(buff,"Accept-Language: en\n");
//strcatbuff(buff,"Accept-Charset: iso-8859-1,*,utf-8\n");
// Custom header(s)
if (strnotempty(retour->req.headers)) {
print_buffer(&bstr, "%s", retour->req.headers);
}
// CRLF de fin d'en tête
print_buffer(&bstr, H_CRLF);
strcatbuff(buff, H_CRLF);
// données complémentaires?
if (search_tag)
if (mode == 0) // GET!
print_buffer(&bstr, "%s",
strcatbuff(buff,
unescape_http(OPT_GET_BUFF(opt),
search_tag + strlen(POSTTOK) + 1));
}
@@ -1137,7 +1171,7 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
if (ioinfo) {
fprintf(ioinfo, "[%d] request for %s%s:\r\n", retour->debugid,
jump_identification(adr), fil);
fprintfio(ioinfo, bstr.buffer, "<<< ");
fprintfio(ioinfo, buff, "<<< ");
fprintf(ioinfo, "\r\n");
fflush(ioinfo);
}
@@ -1147,7 +1181,7 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
// Callback
{
int test_head =
RUN_CALLBACK6(opt, sendhead, bstr.buffer, adr, fil, referer_adr, referer_fil,
RUN_CALLBACK6(opt, sendhead, buff, adr, fil, referer_adr, referer_fil,
retour);
if (test_head != 1) {
deletesoc_r(retour);
@@ -1158,14 +1192,14 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
// Envoi
HTS_STAT.last_request = mtime_local();
if (sendc(retour, bstr.buffer) < 0) { // ERREUR, socket rompue?...
if (sendc(retour, buff) < 0) { // ERREUR, socket rompue?...
//if (sendc(retour->soc,buff) != strlen(buff)) { // ERREUR, socket rompue?...
deletesoc_r(retour); // fermer tout de même
// et tenter de reconnecter
strcpybuff(retour->msg, "Write error");
retour->soc = INVALID_SOCKET;
}
// RX'98
return 0;
}
@@ -1433,7 +1467,7 @@ void treathead(t_cookie * cookie, char *adr, char *fil, htsblk * retour,
p += strlen("max=");
sscanf(p, "%d", &retour->keep_alive_max);
}
if (retour->keep_alive_max <= 1 || retour->keep_alive_t < 1) {
if (retour->keep_alive_max <= 1 || retour->keep_alive_t < 3) {
retour->keep_alive = 0;
}
}
@@ -1752,6 +1786,80 @@ HTSEXT_API void infostatuscode(char *msg, int statuscode) {
}
}
// identique au précédent, sauf que l'on donne adr+fil et non url complète
htsblk xhttpget(httrackp * opt, char *adr, char *fil) {
T_SOC soc;
htsblk retour;
hts_init_htsblk(&retour);
//memset(&retour, 0, sizeof(htsblk));
soc = http_fopen(opt, adr, fil, &retour);
if (soc != INVALID_SOCKET) {
http_fread(soc, &retour);
#if HTS_DEBUG_CLOSESOCK
DEBUG_W("xhttpget: deletehttp\n");
#endif
if (retour.soc != INVALID_SOCKET)
deletehttp(&retour); // fermer
retour.soc = INVALID_SOCKET;
}
return retour;
}
// variation sur un thème...
// réceptionne uniquement un en-tête (HEAD)
// retourne dans xx.adr l'adresse pointant sur le bloc de mémoire de l'en tête
htsblk http_gethead(httrackp * opt, char *adr, char *fil) {
T_SOC soc;
htsblk retour;
hts_init_htsblk(&retour);
//memset(&retour, 0, sizeof(htsblk));
soc = http_xfopen(opt, 1, 0, 1, NULL, adr, fil, &retour); // HEAD, pas de traitement en-tête
if (soc != INVALID_SOCKET) {
http_fread(soc, &retour); // réception en-tête
#if HTS_DEBUG_CLOSESOCK
DEBUG_W("http_gethead: deletehttp\n");
#endif
if (retour.soc != INVALID_SOCKET)
deletehttp(&retour); // fermer
retour.soc = INVALID_SOCKET;
}
return retour;
}
// oui ca ressemble vachement à xhttpget - en étant sobre on peut voir LA différence..
// lecture sur une socket ouverte, le header a déja été envoyé dans le cas de GET
// il ne reste plus qu'à lire les données
// (pour HEAD le header est lu ici!)
void http_fread(T_SOC soc, htsblk * retour) {
//int bufl=TAILLE_BUFFER; // 8Ko de buffer
if (retour)
retour->soc = soc;
if (soc != INVALID_SOCKET) {
// fonction de lecture d'une socket (plus propre)
while(http_fread1(retour) != -1) ;
soc = retour->soc;
if (retour->adr == NULL) {
if (strnotempty(retour->msg) == 0)
sprintf(retour->msg, "Unable to read");
return; // erreur
}
#if HDEBUG
printf("Ok, données reçues\n");
#endif
return;
}
return;
}
// check if data is available
int check_readinput(htsblk * r) {
if (r->soc != INVALID_SOCKET) {
@@ -1794,6 +1902,14 @@ int check_readinput_t(T_SOC soc, int timeout) {
return 0;
}
// lecture d'un bloc sur une socket (ou un fichier!)
// >=0 : nombre d'octets lus
// <0 : fin ou erreur
HTS_INLINE LLint http_fread1(htsblk * r) {
//int bufl=TAILLE_BUFFER; // taille d'un buffer max.
return http_xfread1(r, TAILLE_BUFFER);
}
// idem, sauf qu'ici on peut choisir la taille max de données à recevoir
// SI bufl==0 alors le buffer est censé être de 8kos, et on recoit par bloc de lignes
// en éliminant les cr (ex: header), arrêt si double-lf
@@ -2232,7 +2348,7 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
return INVALID_SOCKET; // erreur création socket impossible
}
// bind this address
if (retour != NULL && strnotempty(retour->req.proxy.bindhost)) {
if (retour != NULL && retour->req.proxy.bindhost[0] != 0) {
t_fullhostent bind_buffer;
const char *error = "unknown error";
@@ -2264,23 +2380,12 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
// connexion non bloquante?
if (!waitconnect) {
#ifdef _WIN32
unsigned long p = 1; // non bloquant
if (ioctlsocket(soc, FIONBIO, &p)) {
const int last_errno = WSAGetLastError();
snprintf(retour->msg, sizeof(retour->msg),
"Non-blocking socket failed: %s", strerror(last_errno));
deletesoc(soc);
return INVALID_SOCKET;
}
#ifdef _WIN32
ioctlsocket(soc, FIONBIO, &p);
#else
const int flags = fcntl(soc, F_GETFL, 0);
if (flags == -1 || fcntl(soc, F_SETFL, flags | O_NONBLOCK) == -1) {
snprintf(retour->msg, sizeof(retour->msg),
"Non-blocking socket failed: %s", strerror(errno));
deletesoc(soc);
return INVALID_SOCKET;
}
ioctl(soc, FIONBIO, &p);
#endif
}
// Connexion au serveur lui même
@@ -2380,6 +2485,10 @@ int ident_url_absolute(const char *url, char *adr, char *fil) {
#if HTS_USEOPENSSL
} else if ((pos = strfield(url, "https:"))) { // HTTPS
strcpybuff(adr, "https://");
#endif
#if HTS_USEMMS
} else if ((pos = strfield(url, "mms:"))) { // mms
strcpybuff(adr, "mms://");
#endif
} else if (scheme) {
return -1; // erreur non reconnu
@@ -3558,6 +3667,10 @@ HTS_INLINE char *jump_protocol(const char *source) {
source += p;
else if ((p = strfield(source, "file:")))
source += p;
#if HTS_USEMMS
else if ((p = strfield(source, "mms:")))
source += p;
#endif
// net_path
if (strncmp(source, "//", 2) == 0)
source += 2;
@@ -4349,7 +4462,7 @@ off_t fsize(const char *s) {
if (!strnotempty(s)) // nom vide: erreur
return -1;
if (stat(s, &st) == 0 && S_ISREG(st.st_mode)) {
if (stat(s, &st) == 0) {
return st.st_size;
} else {
return -1;
@@ -4363,7 +4476,7 @@ off_t fsize_utf8(const char *s) {
if (!strnotempty(s)) // nom vide: erreur
return -1;
if (STAT(s, &st) == 0 && S_ISREG(st.st_mode)) {
if (STAT(s, &st) == 0) {
return st.st_size;
} else {
return -1;
@@ -4498,11 +4611,9 @@ int hts_read(htsblk * r, char *buff, int size) {
#if HTS_WIDE_DEBUG
DEBUG_W("read(%p, %d, %d)\n" _(void *)buff _(int) size _(int) r->fp);
#endif
if (r->fp) {
if (r->fp)
retour = (int) fread(buff, 1, size, r->fp);
if (retour == 0) // can happen with directories (!)
retour = READ_ERROR;
} else
else
retour = READ_ERROR;
} else {
#if HTS_WIDE_DEBUG
@@ -4554,25 +4665,26 @@ int hts_read(htsblk * r, char *buff, int size) {
// 'capsule' contenant uniquement le cache
t_dnscache *_hts_cache(httrackp * opt) {
assert(opt != NULL);
if (opt->state.dns_cache == NULL) {
opt->state.dns_cache = (t_dnscache *) malloct(sizeof(t_dnscache));
memset(opt->state.dns_cache, 0, sizeof(t_dnscache));
}
assert(opt->state.dns_cache != NULL);
return opt->state.dns_cache;
}
// Free DNS cache.
void hts_cache_free(t_dnscache *const root) {
if (root != NULL) {
t_dnscache *cache;
for(cache = root; cache != NULL; ) {
t_dnscache *const next = cache->n;
cache->n = NULL;
freet(cache);
cache = next;
// free the cache
static void hts_cache_free_(t_dnscache * cache) {
if (cache != NULL) {
if (cache->n != NULL) {
hts_cache_free_(cache->n);
}
freet(cache);
}
}
void hts_cache_free(t_dnscache * cache) {
if (cache != NULL && cache->n != NULL) {
hts_cache_free_(cache->n);
cache->n = NULL;
}
}
@@ -4584,10 +4696,8 @@ 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 t_hostent *hts_ghbn(t_dnscache * cache, const char *iadr, t_hostent * retour) {
for(; cache != NULL; cache = cache->n) {
assert(cache != NULL);
assert(iadr != NULL);
if (strcmp(cache->iadr, iadr) == 0) { // ok trouvé
if (cache->host_length > 0) { // entrée valide
if (retour->h_addr_list[0])
@@ -4606,6 +4716,61 @@ static t_hostent *hts_ghbn(const t_dnscache *cache, const char *const iadr, t_ho
return NULL;
}
// tester si iadr a déja été testé (ou en cours de test)
// 0 non encore (en cours)
// 1 ok
// 2 non présent
int hts_dnstest(httrackp * opt, const char *_iadr, int add) {
int ret = 2;
t_dnscache *cache, *tail;
char iadr[HTS_URLMAXSIZE * 2];
// sauter user:pass@ éventuel
strcpybuff(iadr, jump_identification(_iadr));
// couper éventuel :
{
char *a;
if ((a = jump_toport(iadr)))
*a = '\0';
}
#ifdef _WIN32
if (inet_addr(iadr) != INADDR_NONE) // numérique
#else
if (inet_addr(iadr) != (in_addr_t) - 1) // numérique
#endif
return 1;
hts_mutexlock(&opt->state.lock);
for(cache = tail = _hts_cache(opt); cache != NULL; cache = cache->n) {
tail = cache;
if (strcmp(cache->iadr, iadr) == 0) { // ok trouvé
ret = cache->host_length != 0 ? 1 : 0;
break;
}
}
// Add empty entry ?
if (ret == 2 && add) {
assertf(tail != NULL);
assertf(tail->n == NULL);
if (opt->state.dns_cache_nthreads < 16) {
opt->state.dns_cache_nthreads++;
tail->n = (t_dnscache *) calloct(1, sizeof(t_dnscache));
if (tail->n != NULL) {
strcpybuff(tail->n->iadr, iadr);
tail->n->host_length = 0; /* pour le moment rien */
tail->n->n = NULL;
}
} else {
hts_log_print(opt, LOG_DEBUG, "too many threads, not adding another dns resolution in background");
ret = 0;
}
}
hts_mutexrelease(&opt->state.lock);
return ret;
}
HTSEXT_API t_hostent *vxgethostbyname2(char *hostname, void *v_buffer, const char **error) {
t_fullhostent *buffer = (t_fullhostent *) v_buffer;
@@ -4693,11 +4858,6 @@ HTSEXT_API t_hostent *vxgethostbyname(char *hostname, void *v_buffer) {
return vxgethostbyname2(hostname, v_buffer, NULL);
}
HTSEXT_API int check_hostname_dns(char *hostname) {
t_fullhostent buffer;
return vxgethostbyname(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) {
@@ -4706,10 +4866,6 @@ static t_hostent *hts_gethostbyname_(httrackp * opt, const char *_iadr, void *v_
t_dnscache *cache = _hts_cache(opt); // adresse du cache
t_hostent *hp;
assert(opt != NULL);
assert(_iadr != NULL);
assert(v_buffer != NULL);
/* Clear */
fullhostent_init(buffer);
@@ -5051,7 +5207,11 @@ static FILE *hts_dgb_(void) {
if ((hts_dgb_init & 0x80) == 0) {
hts_dgb_init_fp = stderr;
} else {
#ifdef _WIN32_WCE
hts_dgb_init_fp = fopen("\\Temp\\hts-debug.txt", "wb");
#else
hts_dgb_init_fp = FOPEN("hts-debug.txt", "wb");
#endif
if (hts_dgb_init_fp != NULL) {
fprintf(hts_dgb_init_fp, "* Creating file\r\n");
}
@@ -5076,24 +5236,6 @@ static void hts_debug_log_print(const char *format, ...) {
}
}
HTSEXT_API const char* hts_version(void) {
return HTTRACK_VERSIONID;
}
static int ssl_vulnerable(const char *version) {
#ifdef _WIN32
static const char *const match = "OpenSSL 1.0.1";
const size_t match_len = strlen(match);
if (version != NULL && strncmp(version, match, match_len) == 0) {
// CVE-2014-0160
// "OpenSSL 1.0.1g 7 Apr 2014"
const char minor = version[match_len];
return minor == ' ' || ( minor >= 'a' && minor <= 'f' );
}
#endif
return 0;
}
static int hts_init_ok = 0;
HTSEXT_API int hts_init(void) {
const char *dbg_env;
@@ -5115,6 +5257,12 @@ HTSEXT_API int hts_init(void) {
hts_debug_log_print("entering hts_init()"); /* debug */
#ifdef _WIN32_WCE
#ifndef HTS_CECOMPAT
xceinit(L"");
#endif
#endif
/* Init threads (lazy init) */
htsthread_init();
@@ -5142,20 +5290,11 @@ HTSEXT_API int hts_init(void) {
Initialize the OpensSSL library
*/
if (!openssl_ctx) {
const char *version;
SSL_load_error_strings();
SSL_library_init();
// Check CVE-2014-0160.
version = SSLeay_version(SSLEAY_VERSION);
if (ssl_vulnerable(version)) {
fprintf(stderr,
"SSLeay_version(SSLEAY_VERSION) == '%s'\n", version);
abortLog("unable to initialize TLS: OpenSSL version seems vulnerable to heartbleed bug (CVE-2014-0160)");
assertf("OpenSSL version seems vulnerable to heartbleed bug (CVE-2014-0160)" == NULL);
}
///if (SSL_load_error_strings) SSL_load_error_strings();
//if (ERR_load_crypto_strings) ERR_load_crypto_strings();
// if (ERR_load_SSL_strings) ERR_load_SSL_strings(); ???!!!
// OpenSSL_add_all_algorithms();
openssl_ctx = SSL_CTX_new(SSLv23_client_method());
if (!openssl_ctx) {
@@ -5207,13 +5346,11 @@ HTSEXT_API void hts_log_print(httrackp * opt, int type, const char *format, ...)
// Check log level
if (opt->debug < level) {
return;
return;
}
// Dispatch
switch (level) {
case LOG_TRACE:
s_type = "trace";
break;
case LOG_DEBUG:
s_type = "debug";
break;
@@ -5345,7 +5482,7 @@ int multipleStringMatch(const char *s, const char *match) {
}
HTSEXT_API httrackp *hts_create_opt(void) {
#if ( defined(_WIN32) || defined(__ANDROID__) )
#ifdef _WIN32
static const char *defaultModules[] = {
"htsswf", "htsjava", "httrack-plugin", NULL
};
@@ -5376,7 +5513,6 @@ HTSEXT_API httrackp *hts_create_opt(void) {
opt->extdepth = 0; // mais pas à l'extérieur
opt->seeker = 1; // down
opt->urlmode = 2; // relatif par défaut
opt->no_type_change = 0; // change file types
opt->debug = LOG_NOTICE; // small log
opt->getmode = 3; // linear scan
opt->maxsite = -1; // taille max site (aucune)
@@ -5433,9 +5569,6 @@ HTSEXT_API httrackp *hts_create_opt(void) {
opt->convert_utf8 = 1; // convert html to UTF-8
StringCopy(opt->filelist, "");
StringCopy(opt->lang_iso, "en, *");
StringCopy(opt->accept,
"text/html,image/png,image/jpeg,image/pjpeg,image/x-xbitmap,image/svg+xml,image/gif;q=0.9,*/*;q=0.1");
StringCopy(opt->headers, "");
StringCopy(opt->mimedefs, "\n"); // aucun filtre mime (\n IMPORTANT)
StringClear(opt->mod_blacklist);
//
@@ -5460,6 +5593,9 @@ HTSEXT_API httrackp *hts_create_opt(void) {
opt->maxcache = 1048576 * 32; // a peu près 32Mo en cache max -- OPTION NON PARAMETRABLE POUR L'INSTANT --
//opt->maxcache_anticipate=256; // maximum de liens à anticiper
opt->maxtime = -1; // temps max en secondes
#if HTS_USEMMS
opt->mms_maxtime = 60 * 3600; // max time for mms streams (one hour)
#endif
opt->maxrate = 25000; // taux maxi
opt->maxconn = 5.0; // nombre connexions/s
opt->waittime = -1; // wait until.. hh*3600+mm*60+ss
@@ -5530,9 +5666,8 @@ HTSEXT_API void hts_free_opt(httrackp * opt) {
/* Cache */
if (opt->state.dns_cache != NULL) {
t_dnscache *const root = opt->state.dns_cache;
hts_cache_free(opt->state.dns_cache);
opt->state.dns_cache = NULL;
hts_cache_free(root);
}
/* Cancel chain */
@@ -5581,22 +5716,6 @@ HTSEXT_API void hts_free_opt(httrackp * opt) {
}
}
// TEMPORARY - PUT THIS STRUCTURE INSIDE httrackp !
const hts_stat_struct* hts_get_stats(httrackp * opt) {
if (opt == NULL) {
return NULL;
}
HTS_STAT.stat_nsocket = 0;
HTS_STAT.stat_errors = fspc(opt, NULL, "error");
HTS_STAT.stat_warnings = fspc(opt, NULL, "warning");
HTS_STAT.stat_infos = fspc(opt, NULL, "info");
HTS_STAT.nbk = 0;
HTS_STAT.nb = 0;
return &HTS_STAT;
}
// defaut wrappers
static void __cdecl htsdefault_init(t_hts_callbackarg * carg) {
}

View File

@@ -101,9 +101,9 @@ typedef struct htsrequest_proxy htsrequest_proxy;
#endif
struct htsrequest_proxy {
int active;
const char* name;
char name[1024];
int port;
const char* bindhost; // bind this host
char bindhost[256]; // bind this host
};
#ifndef HTS_DEF_FWSTRUCT_htsrequest
@@ -117,12 +117,10 @@ struct htsrequest {
short int range_used; // Range utilisé
short int nocompression; // Pas de compression
short int flush_garbage; // recycled
const char* user_agent;
const char* referer;
const char* from;
const char* lang_iso;
const char* accept;
const char* headers;
char user_agent[128];
char referer[256];
char from[256];
char lang_iso[64];
htsrequest_proxy proxy; // proxy
};
@@ -163,7 +161,7 @@ struct htsblk {
SSL *ssl_con; // connection structure
#endif
char lastmodified[64]; // Last-Modified
char etag[256]; // Etag
char etag[64]; // Etag
char cdispo[256]; // Content-Disposition coupé
LLint crange; // Content-Range
LLint crange_start; // Content-Range
@@ -231,9 +229,6 @@ struct t_dnscache {
// initialize an htsblk structure
void hts_init_htsblk(htsblk * r);
// version
HTSEXT_API const char* hts_version(void);
// fonctions unix/winsock
int hts_read(htsblk * r, char *buff, int size);
@@ -248,7 +243,6 @@ HTSEXT_API int hts_resetvar(void); /* dummy */
HTSEXT_API void hts_debug(int level);
HTSEXT_API httrackp *hts_create_opt(void);
HTSEXT_API void hts_free_opt(httrackp * opt);
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);
@@ -266,6 +260,7 @@ T_SOC http_xfopen(httrackp * opt, int mode, int treat, int waitconnect,
int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, char *xsend,
char *adr, char *fil, char *referer_adr, char *referer_fil,
htsblk * retour);
htsblk httpget(httrackp * opt, char *url);
//int newhttp(char* iadr,char* err=NULL);
T_SOC newhttp(httrackp * opt, const char *iadr, htsblk * retour, int port,
@@ -278,6 +273,8 @@ htsblk http_location(httrackp * opt, char *adr, char *fil, char *loc);
htsblk http_test(httrackp * opt, char *adr, char *fil, char *loc);
int check_readinput(htsblk * r);
int check_readinput_t(T_SOC soc, int timeout);
void http_fread(T_SOC soc, htsblk * retour);
LLint http_fread1(htsblk * r);
void treathead(t_cookie * cookie, char *adr, char *fil, htsblk * retour,
char *rcvd);
void treatfirstline(htsblk * retour, char *rcvd);
@@ -287,6 +284,8 @@ HTSEXT_API void infostatuscode(char *msg, int statuscode);
#endif
// sous-fonctions
htsblk xhttpget(httrackp * opt, char *adr, char *fil);
htsblk http_gethead(httrackp * opt, char *adr, char *fil);
LLint http_xfread1(htsblk * r, int bufl);
HTS_INLINE t_hostent *hts_gethostbyname2(httrackp * opt, const char *iadr,
void *v_buffer, const char **error);
@@ -295,12 +294,12 @@ HTS_INLINE t_hostent *hts_gethostbyname(httrackp * opt, const char *iadr,
#ifndef HTTRACK_DEFLIB
HTSEXT_API t_hostent *vxgethostbyname2(char *hostname, void *v_buffer, const char **error);
HTSEXT_API t_hostent *vxgethostbyname(char *hostname, void *v_buffer);
HTSEXT_API int check_hostname_dns(char *hostname);
#endif
int ftp_available(void);
#if HTS_DNSCACHE
void hts_cache_free(t_dnscache * cache);
int hts_dnstest(httrackp * opt, const char *_iadr, int add);
t_dnscache *_hts_cache(httrackp * opt);
#endif
@@ -571,7 +570,6 @@ HTSEXT_API void hts_log_print(httrackp * opt, int type, const char *format,
|| (code) == 302 \
|| (code) == 303 \
|| (code) == 307 \
|| (code) == 308 \
)
#define HTTP_IS_NOTMODIFIED(code) ( \
(code) == 304 \
@@ -617,6 +615,12 @@ HTS_STATIC int strcmpnocase(char *a, char *b) {
// is this MIME an hypertext MIME (text/html), html/js-style or other script/text type?
#define HTS_HYPERTEXT_DEFAULT_MIME "text/html"
#if HTS_USEMMS
#define OPT_MMS(a) (strfield2((a), "video/x-ms-asf") != 0)
#else
#define OPT_MMS(a) (0)
#endif
#define is_html_mime_type(a) \
( (strfield2((a),"text/html")!=0)\
|| (strfield2((a),"application/xhtml+xml")!=0) \
@@ -637,6 +641,7 @@ HTS_STATIC int strcmpnocase(char *a, char *b) {
(strfield2((a),"audio/x-pn-realaudio")!=0) \
|| (strfield2((a),"audio/x-mpegurl")!=0) \
/*|| (strfield2((a),"text/xml")!=0) || (strfield2((a),"application/xml")!=0) : TODO: content check */ \
|| OPT_MMS(a) \
)
/* Library internal definictions */
@@ -689,6 +694,31 @@ HTS_STATIC int compare_mime(httrackp * opt, const char *mime, const char *file,
#endif
#ifdef _WIN32_WCE_XXC
extern char cwd[MAX_PATH + 1];
HTS_STATIC char *getcwd_ce(char *buffer, int maxlen) {
TCHAR fileUnc[MAX_PATH + 1];
char *plast;
if (cwd[0] == 0) {
GetModuleFileName(NULL, fileUnc, MAX_PATH);
WideCharToMultiByte(CP_ACP, 0, fileUnc, -1, cwd, MAX_PATH, NULL, NULL);
plast = strrchr(cwd, '\\');
if (plast)
*plast = 0;
/* Special trick to keep start menu clean... */
if (_stricmp(cwd, "\\windows\\start menu") == 0)
strcpy(cwd, "\\Apps");
}
if (buffer)
strncpy(buffer, cwd, maxlen);
return cwd;
}
#undef getcwd
#define getcwd getcwd_ce
#endif
/* dirent() compatibility */
#ifdef _WIN32
#define HTS_DIRENT_SIZE 256

234
src/htsmms.c Normal file
View File

@@ -0,0 +1,234 @@
/* ------------------------------------------------------------ */
/*
HTTrack Website Copier, Offline Browser for Windows and Unix
Copyright (C) 1998-2013 Xavier Roche and other contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Important notes:
- We hereby ask people using this source NOT to use it in purpose of grabbing
emails addresses, or collecting any other private information on persons.
This would disgrace our work, and spoil the many hours we spent on it.
Please visit our Website: http://www.httrack.com
*/
/* ------------------------------------------------------------ */
/* File: basic mms protocol manager */
/* Author: Xavier Roche */
/* */
/* The mms routines were written by Nicolas BENOIT, */
/* based on the work of SDP Multimedia and Major MMS */
/* Thanks to all of them! */
/* ------------------------------------------------------------ */
/* Internal engine bytecode */
#define HTS_INTERNAL_BYTECODE
// Gestion protocole mms
#include "htsglobal.h"
#if HTS_USEMMS
#include "htscore.h"
#include "htsmms.h"
#include "mmsrip/mms.h"
#define FTP_STATUS_READY 1001
static int run_launch_mms(MMSDownloadStruct * back);
static void back_launch_mms(void *pP) {
MMSDownloadStruct *pStruct = (MMSDownloadStruct *) pP;
if (pStruct == NULL)
return;
/* Initialize */
hts_init();
/* Run */
run_launch_mms(pStruct);
/* Set as ready */
{
lien_back *back = pStruct->pBack;
back->status = FTP_STATUS_READY;
}
/* Delete structure */
free(pP);
/* Uninitialize */
hts_uninit();
return;
}
/* download cancelled */
static int stop_mms(lien_back * back) {
if (back->stop_ftp) {
strcpybuff(back->r.msg, "Cancelled by User");
back->r.statuscode = STATUSCODE_INVALID;
return 1;
}
return 0;
}
/* Background launch */
void launch_mms(const MMSDownloadStruct * pStruct) {
MMSDownloadStruct *pCopy = calloc(sizeof(MMSDownloadStruct), 1);
memcpy(pCopy, pStruct, sizeof(*pCopy));
hts_newthread(back_launch_mms, (void *) pCopy);
}
/* Code mainly written by Nicolas BENOIT */
static int run_launch_mms(MMSDownloadStruct * pStruct) {
lien_back *back = pStruct->pBack;
httrackp *opt = pStruct->pOpt;
/* */
char url[HTS_URLMAXSIZE * 2];
char catbuff[CATBUFF_SIZE];
char catbuff2[CATBUFF_SIZE];
MMS *mms;
FILE *f;
ssize_t len_written;
uint64_t total_len_written;
int delay = opt->mms_maxtime;
time_t end = time(NULL) + delay;
short checkPending = 0;
ssize_t existingSize = fsize(back->url_sav);
// effacer
strcpybuff(back->r.msg, "");
back->status = STATUS_FTP_TRANSFER;
back->r.statuscode = HTTP_OK;
back->r.size = 0;
/* Create file */
if (existingSize > 0) {
/* back->r.out = fileappend(back->url_sav);
*/
(void) unlink(fconcat(catbuff, back->url_sav, ".old"));
if (rename
(fconcat(catbuff, back->url_sav, ""),
fconcat(catbuff2, back->url_sav, ".old")) == 0) {
checkPending = 1;
}
back->r.out = filecreate(&pStruct->pOpt->state.strc, back->url_sav);
} else {
back->r.out = filecreate(&pStruct->pOpt->state.strc, back->url_sav);
}
if ((f = back->r.out) != NULL) {
// create mms resource
strcpybuff(url, back->url_adr); /* mms:// */
strcatbuff(url, back->url_fil);
if ((mms = mms_create(url, f, NULL, 0, 1)) != NULL) {
if (mms_connect(mms) == 0) {
if (mms_handshake(mms) == 0) {
if ((len_written = mms_write_stream_header(mms)) != -1) {
total_len_written = len_written;
HTS_STAT.HTS_TOTAL_RECV += len_written;
/* not modified */
if (checkPending) {
if (mms->is_live != MMS_LIVE && mms->expected_file_size == existingSize + 50 /* Why 50 additional bytes declared ?? */
) // abort download
{
fclose(back->r.out);
f = back->r.out = NULL;
if (unlink(fconcat(catbuff, back->url_sav, "")) == 0
&& rename(fconcat(catbuff, back->url_sav, ".old"),
fconcat(catbuff2, back->url_sav, "")) == 0) {
back->r.notmodified = 1;
back->r.statuscode = HTTP_OK;
strcpybuff(back->r.msg, "Not modified");
} else {
back->r.statuscode = HTTP_INTERNAL_SERVER_ERROR;
strcpybuff(back->r.msg,
"Unable to rename previous file (not updated)");
}
} else {
(void) unlink(fconcat(catbuff, back->url_sav, ".old"));
}
}
/* begin rip */
if (f != NULL && mms_begin_rip(mms) == 0) {
if (mms->is_live != MMS_LIVE) {
back->r.totalsize = mms->expected_file_size;
back->r.totalsize -= 50; /* Why 50 additional bytes declared ?? */
} else
back->r.totalsize = -1;
/* Start download */
while(!stop_mms(back)) {
len_written = mms_write_stream_data(mms);
if (len_written == 0) {
break;
} else if (len_written == -1) {
back->r.statuscode = HTTP_INTERNAL_SERVER_ERROR;
strcpybuff(back->r.msg, "Unable to write stream data");
break;
}
total_len_written += len_written;
back->r.size = total_len_written;
HTS_STAT.HTS_TOTAL_RECV += len_written;
fflush(f);
if (delay != 0 && end <= time(NULL)) {
delay = -1;
back->r.statuscode = HTTP_OK;
strcpybuff(back->r.msg, "Download interrupted");
break;
}
} // while
back->r.statuscode = HTTP_OK; /* Finished */
} else if (f != NULL) {
back->r.statuscode = HTTP_INTERNAL_SERVER_ERROR;
strcpybuff(back->r.msg, "Can not begin ripping");
}
} else {
back->r.statuscode = HTTP_INTERNAL_SERVER_ERROR;
strcpybuff(back->r.msg, "Can not write stream header");
}
} else {
back->r.statuscode = HTTP_INTERNAL_SERVER_ERROR;
strcpybuff(back->r.msg, "Can not handshake");
}
mms_disconnect(mms);
} else {
back->r.statuscode = HTTP_INTERNAL_SERVER_ERROR;
strcpybuff(back->r.msg, "Can not connect");
}
mms_destroy(mms);
} else {
back->r.statuscode = HTTP_INTERNAL_SERVER_ERROR;
strcpybuff(back->r.msg, "Can not create mms resource");
}
} else {
back->r.statuscode = HTTP_INTERNAL_SERVER_ERROR;
strcpybuff(back->r.msg, "Unable to open local output file");
}
return 0;
}
#endif

64
src/htsmms.h Normal file
View File

@@ -0,0 +1,64 @@
/* ------------------------------------------------------------ */
/*
HTTrack Website Copier, Offline Browser for Windows and Unix
Copyright (C) 1998-2013 Xavier Roche and other contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Important notes:
- We hereby ask people using this source NOT to use it in purpose of grabbing
emails addresses, or collecting any other private information on persons.
This would disgrace our work, and spoil the many hours we spent on it.
Please visit our Website: http://www.httrack.com
*/
/* ------------------------------------------------------------ */
/* File: basic mms protocol manager .h */
/* Author: Xavier Roche */
/* */
/* The mms routines were written by Nicolas BENOIT, */
/* based on the work of SDP Multimedia and Major MMS */
/* Thanks to all of them! */
/* ------------------------------------------------------------ */
#ifndef HTSMMS_DEFH
#define HTSMMS_DEFH
#if HTS_USEMMS
/* Forware definitions */
#ifndef HTS_DEF_FWSTRUCT_lien_back
#define HTS_DEF_FWSTRUCT_lien_back
typedef struct lien_back lien_back;
#endif
#ifndef HTS_DEF_FWSTRUCT_httrackp
#define HTS_DEF_FWSTRUCT_httrackp
typedef struct httrackp httrackp;
#endif
#ifndef HTS_DEF_FWSTRUCT_MMSDownloadStruct
#define HTS_DEF_FWSTRUCT_MMSDownloadStruct
typedef struct MMSDownloadStruct MMSDownloadStruct;
#endif
struct MMSDownloadStruct {
lien_back *pBack;
httrackp *pOpt;
};
void launch_mms(const MMSDownloadStruct * pStruct);
#endif
#endif

View File

@@ -233,6 +233,11 @@ void *getFunctionPtr(void *handle, const char *fncname_) {
return NULL;
}
void *ssl_handle = NULL;
#ifdef _WIN32
void *ssl_handle_2 = NULL;
#endif
void htspe_init(void) {
static int initOk = 0;
@@ -241,22 +246,11 @@ void htspe_init(void) {
/* See CVE-2010-5252 */
#if (defined(_WIN32) && (!defined(_DEBUG)))
{
/* >= Windows Server 2003 (Andy Hewitt) */
const DWORD dwVersion = GetVersion();
const DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
const DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
const int hasSetDllDirectory =
dwMajorVersion >= 6 || ( dwMajorVersion == 5 && dwMinorVersion >= 2 );
/* See KB 2389418
"If this parameter is an empty string (""), the call removes the
current directory from the default DLL search order" */
if (hasSetDllDirectory && !SetDllDirectory("")) {
/* Do no choke on NT or 98SE with KernelEx NT API (James Blough) */
if (dwMajorVersion >= 5) {
assertf(!"SetDllDirectory failed");
}
}
/* See KB 2389418
"If this parameter is an empty string (""), the call removes the
current directory from the default DLL search order" */
if (!SetDllDirectory("")) {
assertf(!"SetDllDirectory failed");
}
#endif
@@ -273,6 +267,15 @@ void htspe_init(void) {
}
void htspe_uninit(void) {
#ifdef _WIN32
CloseHandle(ssl_handle);
CloseHandle(ssl_handle_2);
ssl_handle = NULL;
ssl_handle_2 = NULL;
#else
dlclose(ssl_handle);
ssl_handle = NULL;
#endif
}
static void htspe_log(htsmoduleStruct * str, const char *msg) {

View File

@@ -135,6 +135,7 @@ extern void htspe_uninit(void);
extern int hts_parse_externals(htsmoduleStruct * str);
/*extern int swf_is_available;*/
extern int SSL_is_available;
extern int V6_is_available;
#endif

View File

@@ -146,8 +146,10 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
hash_struct * hash, int ptr, int numero_passe,
const lien_back * headers) {
char catbuff[CATBUFF_SIZE];
const int is_redirect = headers != NULL && HTTP_IS_REDIRECT(headers->r.statuscode);
const char *mime_type = headers != NULL && !is_redirect ? headers->r.contenttype : NULL;
const char *mime_type = (headers
&& !HTTP_IS_REDIRECT(headers->r.
statuscode)) ? headers->r.
contenttype : NULL;
/*const char* mime_type = ( headers && HTTP_IS_OK(headers->r.statuscode) ) ? headers->r.contenttype : NULL; */
lien_back *const back = sback->lnk;
@@ -157,9 +159,9 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
/*char BIGSTK normadr_[HTS_URLMAXSIZE*2]; */
char BIGSTK normadr_[HTS_URLMAXSIZE * 2], normfil_[HTS_URLMAXSIZE * 2];
enum { PROTOCOL_HTTP, PROTOCOL_HTTPS, PROTOCOL_FTP, PROTOCOL_FILE,
PROTOCOL_UNKNOWN };
PROTOCOL_MMS, PROTOCOL_UNKNOWN };
static const char *protocol_str[] =
{ "http", "https", "ftp", "file", "unknown" };
{ "http", "https", "ftp", "file", "mms", "unknown" };
int protocol = PROTOCOL_HTTP;
const char *const adr = jump_identification(adr_complete);
char *fil = fil_complete;
@@ -221,6 +223,8 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
protocol = PROTOCOL_FTP;
} else if (strfield(adr_complete, "file:")) {
protocol = PROTOCOL_FILE;
} else if (strfield(adr_complete, "mms:")) {
protocol = PROTOCOL_MMS;
} else {
protocol = PROTOCOL_HTTP;
}
@@ -262,12 +266,12 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
if (liens != NULL) {
int i;
i = hash_read(hash, normadr, normfil, HASH_STRUCT_ADR_PATH); // recherche table 1 (adr+fil)
i = hash_read(hash, normadr, normfil, 1, opt->urlhack); // recherche table 1 (adr+fil)
if (i >= 0) { // ok, trouvé
strcpybuff(save, liens[i]->sav);
return 0;
}
i = hash_read(hash, normadr, normfil, HASH_STRUCT_ORIGINAL_ADR_PATH); // recherche table 2 (former_adr+former_fil)
i = hash_read(hash, normadr, normfil, 2, opt->urlhack); // recherche table 2 (former_adr+former_fil)
if (i >= 0) { // ok, trouvé
// copier location moved!
strcpybuff(adr_complete, liens[i]->adr);
@@ -286,7 +290,7 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
fil_complete_patche[strlen(fil_complete_patche) - 1] = '\0';
else
strcatbuff(fil_complete_patche, "/");
i = hash_read(hash, normadr, fil_complete_patche, HASH_STRUCT_ORIGINAL_ADR_PATH); // recherche table 2 (former_adr+former_fil)
i = hash_read(hash, normadr, fil_complete_patche, 2, opt->urlhack); // recherche table 2 (former_adr+former_fil)
if (i >= 0) {
// écraser fil et adr (pas former_fil?????)
strcpybuff(adr_complete, liens[i]->adr);
@@ -321,6 +325,33 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
"could not URL-decode string '%s'", fil);
}
#if HTS_USEMMS
/* .asx hack */
if (headers != NULL && headers->r.cdispo[0] != 0
&& strfield(headers->r.contenttype, "video/")
&& strfield2(get_ext(OPT_GET_BUFF(opt), headers->r.cdispo), "asx") == 0) {
ext_chg = 1;
strcpybuff(ext, "asx");
} else if (headers != NULL && headers->r.contenttype[0] != 0
&& strfield2(headers->r.contenttype, "video/x-ms-asf")) {
char *exts = get_ext(OPT_GET_BUFF(opt), headers->url_fil);
if (strfield2(exts, "wmv") == 0) {
ext_chg = 1;
strcpybuff(ext, "wmv");
} else if (strfield2(exts, "asf") == 0) {
ext_chg = 1;
strcpybuff(ext, "asf");
} else if (strfield2(exts, "avi") == 0) {
ext_chg = 1;
strcpybuff(ext, "avi");
} else if (strfield2(exts, "asx") == 0) {
ext_chg = 1;
strcpybuff(ext, "asx");
}
}
#endif
/* replace shtml to html.. */
if (opt->savename_delayed == 2)
is_html = -1; /* ALWAYS delay type */
@@ -359,6 +390,9 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
if (protocol != PROTOCOL_FILE
&& protocol != PROTOCOL_FTP
#if HTS_USEMMS
&& protocol != PROTOCOL_MMS
#endif
) {
// tester type avec requète HEAD si on ne connait pas le type du fichier
if (!((opt->check_type == 1) && (fil[strlen(fil) - 1] == '/'))) // slash doit être html?
@@ -372,16 +406,14 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
s[0] = '\0';
hts_log_print(opt, LOG_DEBUG, "Testing link type (from cache) %s%s",
adr_complete, fil_complete);
if (!HTTP_IS_REDIRECT(r.statuscode)) {
if (strnotempty(r.cdispo)) { /* filename given */
ext_chg = 2; /* change filename */
strcpybuff(ext, r.cdispo);
} else if (!may_unknown2(opt, r.contenttype, fil)) { // on peut patcher à priori?
give_mimext(s, r.contenttype); // obtenir extension
if (strnotempty(s) > 0) { // on a reconnu l'extension
ext_chg = 1;
strcpybuff(ext, s);
}
if (strnotempty(r.cdispo)) { /* filename given */
ext_chg = 2; /* change filename */
strcpybuff(ext, r.cdispo);
} else if (!may_unknown2(opt, r.contenttype, fil)) { // on peut patcher à priori?
give_mimext(s, r.contenttype); // obtenir extension
if (strnotempty(s) > 0) { // on a reconnu l'extension
ext_chg = 1;
strcpybuff(ext, s);
}
}
#ifdef DEFAULT_BIN_EXT
@@ -413,7 +445,7 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
else if (opt->savename_delayed != 0 && !opt->state.stop) {
// Check if the file is ready in backing. We basically take the same logic as later.
// FIXME: we should cleanup and factorize this unholy mess
if (headers != NULL && headers->status >= 0 && !is_redirect) {
if (headers != NULL && headers->status >= 0) {
if (strnotempty(headers->r.cdispo)) { /* filename given */
ext_chg = 2; /* change filename */
strcpybuff(ext, headers->r.cdispo);
@@ -570,6 +602,9 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
// ftp: stop!
if (strfield(mov_url, "ftp://")
#if HTS_USEMMS
|| strfield(mov_url, "mms://")
#endif
) { // ftp, ok on arrête
has_been_moved = 1;
back_maydelete(opt, cache, sback, b); // ok
@@ -710,8 +745,15 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
// Donner nom par défaut?
if (fil[strlen(fil) - 1] == '/') {
if (!strfield(adr_complete, "ftp://")
#if HTS_USEMMS
&& !strfield(adr_complete, "mms://")
#endif
) {
strcatbuff(fil, DEFAULT_HTML); // nommer page par défaut!!
#if HTS_USEMMS
} else if (strfield(adr_complete, "mms://")) {
strcatbuff(fil, DEFAULT_MMS);
#endif
} else {
if (!opt->proxy.active)
strcatbuff(fil, DEFAULT_FTP); // nommer page par défaut (texte)
@@ -721,7 +763,7 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
}
// Changer extension?
// par exemple, php3 sera sauvé en html, cgi en html ou gif, xbm etc.. selon les cas
if (ext_chg && !opt->no_type_change) { // changer ext
if (ext_chg) { // changer ext
char *a = fil + strlen(fil) - 1;
if ((opt->debug > 1) && (opt->log != NULL)) {
@@ -965,7 +1007,6 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
/* release */
RELEASE_ADR();
}
b += strlen(b); // pointer à la fin
break;
case 'H': // host, raw (old mode)
*b = '\0';
@@ -1529,7 +1570,7 @@ int url_savename(char *adr_complete, char *fil_complete, char *save,
printf("\nStart search\n");
#endif
i = hash_read(hash, save, NULL, HASH_STRUCT_FILENAME); // lecture type 0 (sav)
i = hash_read(hash, save, "", 0, 0); // lecture type 0 (sav)
if (i >= 0) {
int sameAdr = (strfield2(liens[i]->adr, normadr) != 0);
int sameFil;

View File

@@ -42,7 +42,9 @@ Please visit our Website: http://www.httrack.com
#include <ctype.h>
#ifdef _WIN32
// pour read
#ifndef _WIN32_WCE
#include <io.h>
#endif
// pour FindFirstFile
#include <winbase.h>
#else
@@ -232,15 +234,9 @@ if (hpsize == sizeof(struct sockaddr_in6)) { \
/* 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'; \
} \
(namebuf)[0]='\0'; \
getnameinfo((struct sockaddr *)&(ss), sslen, \
(namebuf), namebuflen, NULL, 0, NI_NUMERICHOST); \
} while(0)
/* Get protocol ID */

View File

@@ -162,12 +162,6 @@ struct fspc_strc {
int info;
};
/* lien_url */
#ifndef HTS_DEF_FWSTRUCT_lien_url
#define HTS_DEF_FWSTRUCT_lien_url
typedef struct lien_url lien_url;
#endif
#ifndef HTS_DEF_DEFSTRUCT_hts_log_type
#define HTS_DEF_DEFSTRUCT_hts_log_type
typedef enum hts_log_type {
@@ -177,7 +171,6 @@ typedef enum hts_log_type {
LOG_NOTICE,
LOG_INFO,
LOG_DEBUG,
LOG_TRACE,
LOG_ERRNO = 1 << 8
} hts_log_type;
#endif
@@ -289,7 +282,6 @@ struct httrackp {
int depth; // nombre de niveaux de récursion
int extdepth; // nombre de niveaux de récursion à l'éxtérieur
int urlmode; // liens relatifs etc
int no_type_change; // do not change file type according to MIME
int debug; // mode débug log
int getmode; // sauver html, images..
FILE *log; // fichier log
@@ -307,6 +299,7 @@ struct httrackp {
int rateout; // nombre d'octets minium pour le transfert
int maxtime; // temps max en secondes
int maxrate; // taux de transfert max
int mms_maxtime; // max duration of a mms file
float maxconn; // nombre max de connexions/s
int waittime; // démarrage programmé
int cache; // génération d'un cache
@@ -362,11 +355,8 @@ struct httrackp {
String urllist; // fichier liste de filtres à inclure
htsfilters filters; // contient les pointeurs pour les filtres
hash_struct *hash; // hash structure
lien_url **liens; // liens
robots_wizard *robotsptr; // robots ptr
String lang_iso; // en, fr ..
String accept; // Accept:
String headers; // Additional headers
String mimedefs; // ext1=mimetype1\next2=mimetype2..
String mod_blacklist; // (3.41)
int convert_utf8; // filenames UTF-8 conversion (3.46)

View File

@@ -35,7 +35,9 @@ Please visit our Website: http://www.httrack.com
/* Internal engine bytecode */
#define HTS_INTERNAL_BYTECODE
#ifndef _WIN32_WCE
#include <fcntl.h>
#endif
#include <ctype.h>
/* File defs */
@@ -82,7 +84,7 @@ Please visit our Website: http://www.httrack.com
if (ht_buff==NULL) { \
printf("PANIC! : Not enough memory [%d]\n", __LINE__); \
XH_uninit; \
abortLogFmt("not enough memory for current html document in HT_ADD_CHK : realloct("LLintP") failed" _ (LLint) ht_size); \
abortLogFmt("not enough memory for current html document in HT_ADD_CHK : realloct("LLintP") failed" _ ht_size); \
abort(); \
} \
} \
@@ -135,7 +137,7 @@ Please visit our Website: http://www.httrack.com
if (ht_buff==NULL) { \
printf("PANIC! : Not enough memory [%d]\n",__LINE__); \
XH_uninit; \
abortLogFmt("not enough memory for current html document in HT_ADD_START : malloct("LLintP") failed" _ (LLint) ht_size); \
abortLogFmt("not enough memory for current html document in HT_ADD_START : malloct("LLintP") failed" _ ht_size); \
abort(); \
} \
ht_buff[0]='\0'; \
@@ -292,7 +294,7 @@ Please visit our Website: http://www.httrack.com
strcpybuff(liens[lien_tot]->fil,F); \
strcpybuff(liens[lien_tot]->sav,S); \
liens_record_sav_len(liens[lien_tot]); \
hash_write(hashptr,lien_tot); \
hash_write(hashptr,lien_tot,opt->urlhack); \
} \
}
@@ -1698,6 +1700,9 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
#if HTS_USEOPENSSL
|| (strfield(tempo, "https:")
)
#endif
#if HTS_USEMMS
|| strfield(tempo, "mms:")
#endif
) // ok pas de problème
url_ok = 1;
@@ -3193,7 +3198,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
//
// On part de la fin et on essaye de se presser (économise temps machine)
{
int i = hash_read(hash, save, NULL, 0); // lecture type 0 (sav)
int i = hash_read(hash, save, "", 0, opt->urlhack); // lecture type 0 (sav)
if (i >= 0) {
if ((opt->debug > 1) && (opt->log != NULL)) {
@@ -3225,6 +3230,9 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
if (!just_test_it) {
if ((!strfield(adr, "ftp://")) // non ftp
&& (!strfield(adr, "file://"))
#if HTS_USEMMS
&& (!strfield(adr, "mms://"))
#endif
) { // non file
if (opt->robots) { // récupérer robots
if (ishtml(opt, fil) != 0) { // pas la peine pour des fichiers isolés
@@ -3630,7 +3638,7 @@ int hts_mirror_check_moved(htsmoduleStruct * str,
liens[liens[ptr]->precedent]->adr,
liens[liens[ptr]->precedent]->fil, opt, liens, lien_tot,
sback, cache, hash, ptr, numero_passe, NULL) != -1) {
if (hash_read(hash, mov_sav, NULL, HASH_STRUCT_FILENAME) < 0) { // n'existe pas déja
if (hash_read(hash, mov_sav, "", 0, 0) < 0) { // n'existe pas déja
// enregistrer lien (MACRO) avec SAV IDENTIQUE
liens_record(mov_adr, mov_fil, liens[ptr]->sav, "", "");
//liens_record(mov_adr,mov_fil,mov_sav,"","");
@@ -4067,7 +4075,7 @@ void hts_mirror_process_user_interaction(htsmoduleStruct * str,
if (url_savename
(add_adr, add_fil, add_sav, NULL, NULL, NULL, NULL, opt, liens,
lien_tot, sback, cache, hash, ptr, numero_passe, NULL) != -1) {
if (hash_read(hash, add_sav, NULL, HASH_STRUCT_FILENAME) < 0) { // n'existe pas déja
if (hash_read(hash, add_sav, "", 0, 0) < 0) { // n'existe pas déja
// enregistrer lien (MACRO)
liens_record(add_adr, add_fil, add_sav, "", "");
if (liens[lien_tot] != NULL) { // OK, pas d'erreur
@@ -4617,7 +4625,7 @@ int hts_wait_delayed(htsmoduleStruct * str, char *adr, char *fil, char *save,
}
/* Check if the file was recorded already (necessary for redirects) */
if (hash_read(hash, save, NULL, HASH_STRUCT_FILENAME) >= 0) {
if (hash_read(hash, save, "", 0, opt->urlhack) >= 0) {
if (loops == 0) { /* Should not happend */
hts_log_print(opt, LOG_ERROR,
"Duplicate entry in hts_wait_delayed() cancelled: %s%s -> %s",
@@ -4645,7 +4653,7 @@ int hts_wait_delayed(htsmoduleStruct * str, char *adr, char *fil, char *save,
/* We added the link before the parser recorded it -- the background download MUST NOT clean silently this entry! (Petr Gajdusek) */
back[b].early_add = 1;
/* Cache read failed because file does not exist (bad delayed name!)
/* Cache read failed because file does not exists (bad delayed name!)
Just re-add with the correct name, as we know the MIME now!
*/
if (back[b].r.statuscode == STATUSCODE_INVALID && back[b].r.adr == NULL) {
@@ -4657,8 +4665,7 @@ int hts_wait_delayed(htsmoduleStruct * str, char *adr, char *fil, char *save,
back_copy_static(&back[b], &delayed_back);
/* Delete entry */
back[b].r.statuscode = 0; /* TEMPORARY INVESTIGATE WHY WE FETCHED A SOCKET HERE */
back_maydelete(opt, cache, sback, b); // cancel
back_delete(opt, cache, sback, b); // cancel
b = -1;
/* Recompute filename with MIME type */
@@ -4834,7 +4841,11 @@ int hts_wait_delayed(htsmoduleStruct * str, char *adr, char *fil, char *save,
}
// ftp: stop!
if (strfield(mov_url, "ftp://")) {
if (strfield(mov_url, "ftp://")
#if HTS_USEMMS
|| strfield(mov_url, "mms://")
#endif
) {
strcpybuff(adr, mov_adr);
strcpybuff(fil, mov_fil);
break;
@@ -4894,7 +4905,6 @@ int hts_wait_delayed(htsmoduleStruct * str, char *adr, char *fil, char *save,
/* Finalize now as we have the type */
if (back[b].status == STATUS_READY) {
if (!back[b].finalized) {
hts_log_print(opt, LOG_TRACE, "finalizing as we have the type");
back_finalize(opt, cache, sback, b);
}
}

View File

@@ -382,7 +382,7 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
{"user", "Mozilla/4.5 (compatible; HTTrack 3.0x; Windows 98)"},
{"footer",
"<!-- Mirrored from %s%s by HTTrack Website Copier/3.x [XR&CO'2013], %s -->"},
{"url2", "+*.png +*.gif +*.jpg +*.jpeg +*.css +*.js -ad.doubleclick.net/*"},
{"url2", "+*.png +*.gif +*.jpg +*.css +*.js -ad.doubleclick.net/*"},
{NULL, NULL}
};
int i = 0;
@@ -1442,7 +1442,7 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
int htslang_init(void) {
if (NewLangList == NULL) {
NewLangList = inthash_new(0);
NewLangList = inthash_new(NewLangListSz);
if (NewLangList == NULL) {
abortLog("Error in lang.h: not enough memory");
} else {
@@ -1485,8 +1485,8 @@ static int htslang_load(char *limit_to, char *path) {
//
if (!limit_to) {
LANG_DELETE();
NewLangStr = inthash_new(0);
NewLangStrKeys = inthash_new(0);
NewLangStr = inthash_new(NewLangStrSz);
NewLangStrKeys = inthash_new(NewLangStrKeysSz);
if ((NewLangStr == NULL) || (NewLangStrKeys == NULL)) {
abortLog("Error in lang.h: not enough memory");
} else {

View File

@@ -35,7 +35,6 @@ Please visit our Website: http://www.httrack.com
#ifndef HTS_SERVER_DEFH
#define HTS_SERVER_DEFH
#include <sys/stat.h>
#include "htsnet.h"
/* String */
@@ -86,11 +85,6 @@ extern httrackp *global_opt;
#define is_quote(c) ( ((c)=='\"') || ((c)=='\'') )
#define is_retorsep(c) ( ((c)==10) || ((c)==13) || ((c)==9) )
#undef min
#undef max
#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);
@@ -228,7 +222,7 @@ static int linput(FILE * fp, char *s, int max) {
}
static int linput_trim(FILE * fp, char *s, int max) {
int rlen = 0;
char *ls = (char *) malloc(max + 2);
char *ls = (char *) malloct(max + 2);
s[0] = '\0';
if (ls) {
@@ -252,7 +246,7 @@ static int linput_trim(FILE * fp, char *s, int max) {
}
}
//
free(ls);
freet(ls);
}
return rlen;
}

View File

@@ -39,6 +39,11 @@ Please visit our Website: http://www.httrack.com
#endif
#ifdef _WIN32
#include "windows.h"
#ifdef _WIN32_WCE
#ifndef HTS_CECOMPAT
#include "cethread.h"
#endif
#endif
#endif
#ifndef USE_BEGINTHREAD
#error needs USE_BEGINTHREAD

View File

@@ -161,6 +161,12 @@ int ident_url_relatif(const char *lien, const char *origin_adr,
} else {
ok = -2; // non supporté
}
#if HTS_USEMMS
} else if (strfield(lien, "mms://")) {
if (ident_url_absolute(lien, adr, fil) == -1) {
ok = -1; // erreur URL
}
#endif
#if HTS_USEOPENSSL
} else if (strfield(lien, "https://")) {
// Note: ftp:foobar.gif is not valid
@@ -171,18 +177,15 @@ int ident_url_relatif(const char *lien, const char *origin_adr,
} else if ((scheme) && ((!strfield(lien, "http:"))
&& (!strfield(lien, "https:"))
&& (!strfield(lien, "ftp:"))
#if HTS_USEMMS
&& (!strfield(lien, "mms:"))
#endif
)) {
ok = -1; // unknown scheme
} else { // c'est un lien relatif
// On forme l'URL complète à partie de l'url actuelle
// et du chemin actuel si besoin est.
// sanity check
if (origin_adr == NULL || origin_fil == NULL
|| *origin_adr == '\0' || *origin_fil == '\0') {
return -1;
}
// copier adresse
if (((int) strlen(origin_adr) < HTS_URLMAXSIZE)
&& ((int) strlen(origin_fil) < HTS_URLMAXSIZE)
@@ -200,6 +203,12 @@ int ident_url_relatif(const char *lien, const char *origin_adr,
lien += 4;
strcpybuff(adr, "ftp://"); // même adresse forcée en ftp
strcatbuff(adr, jump_protocol(origin_adr));
#if HTS_USEMMS
} else if (strfield(lien, "mms:")) {
lien += 4;
strcpybuff(adr, "mms://"); // même adresse forcée en ftp
strcatbuff(adr, jump_protocol(origin_adr));
#endif
} else {
strcpybuff(adr, origin_adr); // même adresse ; et même éventuel protocole
}
@@ -980,7 +989,7 @@ HTSEXT_API char *hts_getcategories(char *path, int type) {
String iname = STRING_EMPTY;
if (type == 1) {
hashCateg = inthash_new(0);
hashCateg = inthash_new(127);
StringCat(categ, "Test category 1");
StringCat(categ, "\r\nTest category 2");
}

View File

@@ -61,7 +61,6 @@ Please visit our Website: http://www.httrack.com
#include "htsinthash.c"
#include "htsmd5.c"
#include "md5.c"
#undef HTS_PRINTF_FUN
#include "htsserver.h"
#include "htsweb.h"

View File

@@ -153,7 +153,7 @@ static int hts_acceptlink_(httrackp * opt, int ptr, int lien_tot,
/* Already exists? Then, we know that we knew that this link had to be known */
if (adr[0] != '\0' && fil[0] != '\0' && opt->hash != NULL
&& hash_read(opt->hash, adr, fil, 1) >= 0) {
&& hash_read(opt->hash, adr, fil, 1, opt->urlhack) >= 0) {
return 0; /* Yokai */
}
// -------------------- PRELUDE OF PHASE 3-BIS --------------------
@@ -842,7 +842,11 @@ static int hts_acceptlink_(httrackp * opt, int ptr, int lien_tot,
if (just_test_it) {
if (forbidden_url == 1) {
if (opt->travel & 256) { // tester tout de même
if (strfield(adr, "ftp://") == 0) { // PAS ftp!
if (strfield(adr, "ftp://") == 0
#if HTS_USEMMS
&& strfield(adr, "mms://") == 0
#endif
) { // PAS ftp!
forbidden_url = 1; // oui oui toujours interdit (note: sert à rien car ==1 mais c pour comprendre)
*just_test_it = 1; // mais on teste
hts_log_print(opt, LOG_DEBUG, "Testing link %s%s", adr, fil);

View File

@@ -53,14 +53,12 @@ Please visit our Website: http://www.httrack.com
/* Note: utf-8 */
int hts_zunpack(char *filename, char *newfile) {
int ret = -1;
char catbuff[CATBUFF_SIZE];
if (filename != NULL && newfile != NULL) {
if (filename && newfile) {
if (filename[0] && newfile[0]) {
char catbuff[CATBUFF_SIZE];
FILE *const in = FOPEN(fconv(catbuff, filename), "rb");
const int fd = in != NULL ? fileno(in) : -1;
// Note: we must dup to be able to flose cleanly.
gzFile gz = fd != -1 ? gzdopen(dup(fd), "rb") : NULL;
// not: NOT an UTF-8 filename
gzFile gz = gzopen(filename, "rb");
if (gz) {
FILE *const fpout = FOPEN(fconv(catbuff, newfile), "wb");
@@ -72,7 +70,7 @@ int hts_zunpack(char *filename, char *newfile) {
do {
char BIGSTK buff[1024];
nr = gzread(gz, buff, sizeof(buff));
nr = gzread(gz, buff, 1024);
if (nr > 0) {
size += nr;
if (fwrite(buff, 1, nr, fpout) != nr)
@@ -85,9 +83,6 @@ int hts_zunpack(char *filename, char *newfile) {
gzclose(gz);
ret = (int) size;
}
if (in != NULL) {
fclose(in);
}
}
}
return ret;

View File

@@ -52,14 +52,9 @@ typedef enum hts_log_type {
LOG_NOTICE,
LOG_INFO,
LOG_DEBUG,
LOG_TRACE,
LOG_ERRNO = 1 << 8
} hts_log_type;
#endif
#ifndef HTS_DEF_FWSTRUCT_hts_stat_struct
#define HTS_DEF_FWSTRUCT_hts_stat_struct
typedef struct hts_stat_struct hts_stat_struct;
#endif
/* Helpers for plugging callbacks
requires: htsdefines.h */
@@ -115,8 +110,6 @@ HTSEXT_API void hts_log_print(httrackp * opt, int type, const char *format,
/* Infos */
HTSEXT_API const char *hts_get_version_info(httrackp * opt);
HTSEXT_API const char *hts_is_available(void);
HTSEXT_API const char* hts_version(void);
HTSEXT_API const hts_stat_struct* hts_get_stats(httrackp * opt);
/* Wrapper functions */
HTSEXT_API int htswrap_init(void); // DEPRECATED - DUMMY FUNCTION

View File

@@ -876,12 +876,14 @@ static void sig_leave(int code) {
static void signal_handlers(void) {
#ifdef _WIN32
#ifndef _WIN32_WCE
#if 0 /* BUG366763 */
signal(SIGINT, sig_ask); // ^C
#else
signal(SIGINT, sig_leave); // ^C
#endif
signal(SIGTERM, sig_finish); // kill <process>
#endif
#else
#if 0 /* BUG366763 */
signal(SIGHUP, sig_back); // close window

View File

@@ -21,6 +21,9 @@ struct MD5Context {
unsigned char in[64];
uint32 buf[4];
uint32 bits[2];
#ifdef _WIN32_WCE
uint32 pad[2];
#endif
int doByteReverse;
};

27
src/mmsrip/AUTHORS Normal file
View File

@@ -0,0 +1,27 @@
Nicolas BENOIT (main developper)
nbenoit@tuxfamily.org
http://nbenoit.tuxfamily.org
Major MMS (author of mmsclient)
http://www.geocities.com/majormms
SDP Multimedia (author of the only doc about MMS)
http://get.to/sdp
Aurelien REQUIEM (author of mmsrip's ebuild script)
aurelien@menfin.net
Luis COSTA (initial idea and patch for the -d/--delay option)
izhirahider@gmail.com
Jeff FULMER (Solaris port)
jeff@joedog.org
Federico SIMONCELLI (RPMs for Fedora Core 4)
federico.simoncelli@gmail.com
Kyuzz (Fix for Cygwin compilation)
kyuzz.org
Xavier ROCHE (Initial port to Win32)
roche@httrack.com

340
src/mmsrip/COPYING Normal file
View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

156
src/mmsrip/ChangeLog Normal file
View File

@@ -0,0 +1,156 @@
2006-01-24 Nicolas BENOIT <nbenoit@tuxfamily.org>
* README, NEWS: getting ready for 0.7.0 release.
* gentoo/mmsrip-0.7.0.ebuild: ebuild script for 0.7.0 release.
* spec/mmsrip.spec: updated for 0.7.0 release.
2006-01-23 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/mms.h, src/mms.c, src/main.c, doc/mmsrip.1: renamed compatibility mode to trick enabled mode (-c/--compat switches are now -k/--trick).
* src/mms.c, src/main.c: fixed parsing of urls that look like 'stream.asf?digest=7Q2bjXo&provider=lala'.
* src/mms.c, src/mms.h, src/main.c, doc/mmsrip.1, configure.ac: replaced configure's --enable-debug switch by a -gFILE/--debug=FILE runtime switch.
* doc/mmsrip.1: improved presentation.
2006-01-22 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/mms.c: fixed presentation in debug output.
* AUTHORS: updated.
* src/mms.c: improved debug ouput for header interpretation.
* src/mms.c: fixed expected file size.
* src/mms.c: added a few calls to mms_get_32() for code lisibility.
* src/mms.c: added mms_get_64() function (improves lisibility in mms_interp_header()).
* src/mms.c: improved ASF header interpretation.
* src/mms.h, src/mms.c, src/main.c, doc/mmsrip.1: added compatibility mode and -c/--compat switches.
* src/main.c: minor presentation improvements.
* src/mms.c: added an entry for mmsh:// protocol though we don't support it.
2006-01-21 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/mms.h, src/mms.c, src/error.c, src/error.h, src/main.c, configure.ac: fixed compilation on Win32 (thanks to Xavier ROCHE for the initial port).
* AUTHORS: updated.
* src/mms.c: fixed URL parsing (mmst:// is now ok).
* src/mms.c, doc/mmsrip.1: the user should read the manpage when the server sends a no auth error.
* configure.ac: added a switch to enable debug output to stdout.
2006-01-20 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/mms.h, src/main.c, configure.ac: fixed compilation on Solaris (from Jeff FULMER's Solaris port).
* AUTHORS: updated.
* gentoo/mmsrip-0.6.6.ebuild: ebuild script for 0.6.6 release.
* spec/mmsrip.spec: spec file for RPM building (thanks to Federico SIMONCELLI).
* src/mms.c, configure.ac: added the display of the ripping speed.
2006-01-17 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/mms.h: fixed compilation on Cygwin (greetings to Kyuzz for bug reporting).
2006-01-06 Nicolas BENOIT <nbenoit@tuxfamily.org>
* configure.ac, src/common.h: 0.6.5 release.
2006-01-06 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/mms.c: fixed a call to error().
* src/mms.h: reordered some error codes.
* src/main.c: improved the error code returned by the program.
* doc/mmsrip.1: added some documentation about the program's returned value.
* gentoo/mmsrip-0.6.5.ebuild: ebuild script for 0.6.5 release.
* README, NEWS: getting ready for 0.6.5 release.
2005-11-23 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/mms.h, src/mms.c, src/main.c: replaced a few values with #defines.
* src/mms.c: added the support for no auth errors (this happens sometimes, for example on canalplus.fr).
2005-07-09 Nicolas BENOIT <nbenoit@tuxfamily.org>
* configure.ac, src/common.h: 0.6.4 release.
2005-07-09 Nicolas BENOIT <nbenoit@tuxfamily.org>
* doc/mmsrip.1: added man page.
* doc/Makefile.am, Makefile.am, configure.ac: added the man page to the package.
* src/main.c: fixed a compilation warning about variable `end` initialization.
* src/mms.c: fixed a potential security issue in the handling of files containing more than 20 streams (patch ported from MPlayer).
* src/mms.c: fixed a bug in the media stream MBR selection that prevented ASF files from being ripped properly (bug reported by Jozef RIHA).
* gentoo/mmsrip-0.6.4.ebuild: ebuild script for 0.6.4 release.
* README, NEWS: getting ready for 0.6.4 release.
2005-06-05 Nicolas BENOIT <nbenoit@tuxfamily.org>
* configure.ac, src/common.h: 0.6.2 release.
2005-06-05 Nicolas BENOIT <nbenoit@tuxfamily.org>
* Makefile.am: ebuild script moved in a dedicated gentoo directory.
* gentoo/mmsrip-0.6.2.ebuild: ebuild script for 0.6.2 release.
* src/main.c: added '-d' switch which makes mmsrip exit after the specified delay (idea and patch by Luis COSTA).
* src/main.c: fixed bug that made mmsrip attempt to use invalid URLs.
* AUTHORS: updated.
* src/main.c: added support for long options.
* README, NEWS: getting ready for 0.6.2 release.
2005-05-29 Nicolas BENOIT <nbenoit@tuxfamily.org>
* configure.ac: 0.6.0 release.
2005-05-29 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/main.c: added '-q' switch which makes mmsrip quiet.
* src/mms.c, src/mms.h: added support for quiet mode.
* src/main.c: added '-t' switch which makes mmsrip check stream availability only.
* src/main.c: added '-o' switch which makes mmsrip output stream to specified file.
* src/main.c: fixed a bug in args handling.
* README, NEWS, src/common.h: getting ready for 0.6.0 release.
2005-05-28 Nicolas BENOIT <nbenoit@tuxfamily.org>
* mmsrip-0.6.0.ebuild: added Aurelien REQUIEM's ebuild.
* README: updated.
* AUTHORS: updated.
* Makefile.am: added ebuild script to EXTRA_DIST.
* configure.ac: added CVS infos.
2005-02-21 Nicolas BENOIT <nbenoit@tuxfamily.org>
* configure.ac, src/common.h: 0.4.2 release.
2005-02-21 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/mms.c: Removed bad EOF handling in mms_recv_packet().
* README, NEWS: Getting ready for 0.4.2.
2005-02-20 Nicolas BENOIT <nbenoit@tuxfamily.org>
* configure.ac, src/common.h: 0.4.1 release.
2005-02-20 Nicolas BENOIT <nbenoit@tuxfamily.org>
* src/main.c: Fixed bug with multiple streams (mmsrip used to download the same stream every time).
* configure.ac: Removed unnecessary checks.
* src/mms.c: Removed strndup() because a lot of people don't have it.
* README, NEWS: Getting ready for 0.4.1.
2005-02-20 Nicolas BENOIT <nbenoit@tuxfamily.org>
* configure.ac, src/common.h: 0.4.0 release.

68
src/mmsrip/NEWS Normal file
View File

@@ -0,0 +1,68 @@
MMS Ripper v0.7.0:
====================
- Added '-k' and '--trick' switches that activate a trick for some recalcitrant servers.
- Added the display of the ripping speed.
- Added '-gFILE' and '--debug=FILE' switches which activate debug output to specified file.
- Fixed parsing of urls that include options after file name (stream.asf?dig=7QXo&pr=lala).
- Fixed protocol checking in URL parsing.
- Fixed expected file size calculation.
- Fixed compilation on Solaris, Cygwin and Win32 (check AUTHORS file for greetings).
- Improved debug output.
- Improved ASF header interpretation.
- Improved presentation in manpage.
- Minor code cleanups.
- A spec file is now distributed.
MMS Ripper v0.6.5:
====================
- Added the handling of the no auth error during streaming.
(this should fix mmsrip behavior on some servers such as canalplus.fr)
- Improved the diagnostic value returned by mmsrip in case of error (please read the manpage).
MMS Ripper v0.6.4:
====================
- Added a man page.
- Fixed a compilation warning.
- Fixed a potential security issue.
- Fixed the ripping of some ASF files (bug reported by Jozef RIHA).
MMS Ripper v0.6.2:
====================
- Added '-d' switch which makes mmsrip exit after DELAY seconds.
- Added support for long options.
- Fixed bug that made mmsrip attempt to use invalid URLs.
MMS Ripper v0.6.0:
====================
- Added '-q' switch which enables quiet mode.
- Added '-t' switch which makes mmsrip check stream availability only.
- Added '-o' switch so the user can choose the output file for every stream.
- Fixed a bug in arguments handling.
MMS Ripper v0.4.2:
====================
- Fixed a serious bug in packet reception (mmsrip went crazy).
MMS Ripper v0.4.1:
====================
- Fixed a bug that made mmsrip download the same stream every time.
- Compilation fixes.
MMS Ripper v0.4.0:
====================
- First Release of mmsrip.

37
src/mmsrip/README Normal file
View File

@@ -0,0 +1,37 @@
MMS Ripper release 0.7.0
These are the release notes for mmsrip version 0.7.0
Read them carefully, as they tell you what this is all about.
WHAT IS MMSRIP ?
MMSRIP allows you to save on your hard-disk the content being streamed
by an MMS server. This program has been written for personnal use, so
don't blame me if you think I am stupid doing such tool for the others.
It should run on every POSIX compliant Operating System, but I can't
give you any complete list.
HOW TO INSTALL ?
Read the file INSTALL in order to get the answer of this question... ;)
If you use a gentoo based distribution, enjoy the ebuild script contributed by Aurelien REQUIEM.
If you use a RPM based distribution, you may use the spec file provided by Frederico SIMONCELLI.
HOW TO RUN ?
Once you have compiled & installed, you should be able to run the program.
IMPORTANT NOTE
All the credits go to SDP Multimedia and Major MMS.
--
$RCSfile: README,v $
$Date: 2006/01/24 18:13:07 $ - $Revision: 1.13 $

50
src/mmsrip/common.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* $RCSfile: common.h,v $
* $Date: 2006/01/17 19:59:27 $ - $Revision: 1.11 $
*
* This file is distributed as a part of MMSRIP ( MMS Ripper ).
* Copyright (c) 2005-2006 Nicolas BENOIT
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __COMMON_H__
#define __COMMON_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#define PROGRAM_SHORT_NAME "mmsrip"
#define PROGRAM_FULL_NAME "MMS Ripper"
#define PROGRAM_VERSION "0.7.0-rc1"
#endif
#define PROGRAM_AUTHORS "Nicolas BENOIT <nbenoit@tuxfamily.org>"
#define PROGRAM_HELPERS "SDP Multimedia and Major MMS"
/*
* quick struct in order to make list of streams
*/
typedef struct
{
void *next;
char *stream;
char *output;
} STREAM_LIST;
#endif

117
src/mmsrip/error.c Normal file
View File

@@ -0,0 +1,117 @@
/*
* $RCSfile: error.c,v $
* $Date: 2006/01/21 20:09:57 $ - $Revision: 1.7 $
*
* This file is distributed as a part of MMSRIP ( MMS Ripper ).
* Copyright (c) 2005-2006 Nicolas BENOIT
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "common.h"
#include "error.h"
/*
* Prints A Warning
*/
#ifdef HAVE_VSNPRINTF
void
warning ( const char *prod,
const char *format,
... )
{
char *message;
va_list ap;
if ( format == NULL )
return;
message = ( char * ) malloc ( ERROR_MSG_LEN );
va_start ( ap, format );
vsnprintf ( message, ERROR_MSG_LEN, format, ap );
va_end ( ap );
if ( prod != NULL )
fprintf ( stderr, "warning in %s(): %s.\n", prod, message );
else
fprintf ( stderr, "warning: %s.\n", message );
free ( message );
}
#else
void
warning ( const char *prod,
const char *message )
{
if ( message == NULL )
return;
if ( prod != NULL )
fprintf ( stderr, "warning in %s(): %s.\n", prod, message );
else
fprintf ( stderr, "warning: %s.\n", message );
}
#endif
/*
* Prints An Error Message
*/
#ifdef HAVE_VSNPRINTF
void
error ( const char *prod,
const char *format,
... )
{
char *message;
va_list ap;
if ( format == NULL )
return;
message = ( char * ) malloc ( ERROR_MSG_LEN );
va_start ( ap, format );
vsnprintf ( message, ERROR_MSG_LEN, format, ap );
va_end ( ap );
if ( prod != NULL )
fprintf ( stderr, "error in %s(): %s.\n", prod, message );
else
fprintf ( stderr, "error: %s.\n", message );
free ( message );
}
#else
void
error ( const char *prod,
const char *message )
{
if ( message == NULL )
return;
if ( prod != NULL )
fprintf ( stderr, "error in %s(): %s.\n", prod, message );
else
fprintf ( stderr, "error: %s.\n", message );
}
#endif

40
src/mmsrip/error.h Normal file
View File

@@ -0,0 +1,40 @@
/*
* $RCSfile: error.h,v $
* $Date: 2006/01/21 20:09:57 $ - $Revision: 1.4 $
*
* This file is distributed as a part of MMSRIP ( MMS Ripper ).
* Copyright (c) 2005-2006 Nicolas BENOIT
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ERROR_H__
#define __ERROR_H__
#ifdef HAVE_VSNPRINTF
#include <stdarg.h>
#define ERROR_MSG_LEN 128
void warning ( const char *, const char *, ... );
void error ( const char *, const char *, ... );
#else
void warning ( const char *, const char * );
void error ( const char *, const char * );
#endif
#endif

753
src/mmsrip/main.c Normal file
View File

@@ -0,0 +1,753 @@
/*
* $RCSfile: main.c,v $
* $Date: 2006/01/23 20:30:42 $ - $Revision: 1.32 $
*
* This file is distributed as a part of MMSRIP ( MMS Ripper ).
* Copyright (c) 2005-2006 Nicolas BENOIT
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include "common.h"
#include "mms.h"
#include "error.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
/*
* options
*/
#if defined(SOLARIS) || defined(sun)
static char * options = "ahvtqko:d:g:";
#else
static char * options = "-ahvtqko:d:g:";
#endif
#ifdef HAVE_GETOPT_LONG
static struct option long_options[] = {
{"about", 0, NULL, 'a'},
{"version", 0, NULL, 'v'},
{"help", 0, NULL, 'h'},
{"test", 0, NULL, 't'},
{"quiet", 0, NULL, 'q'},
{"trick", 0, NULL, 'k'},
{"output", 1, NULL, 'o'},
{"delay", 1, NULL, 'd'},
{"debug", 1, NULL, 'g'},
{NULL, 0, NULL, 0 }
};
#endif
/*
* usage
*/
void
usage ( void )
{
fprintf ( stderr, "%s (%s) version %s\n\n", PROGRAM_SHORT_NAME, PROGRAM_FULL_NAME, PROGRAM_VERSION );
fprintf ( stderr, "usage: %s <[-oFILE] stream url> ...\n\n", PROGRAM_SHORT_NAME );
#ifdef HAVE_GETOPT_LONG
fprintf ( stderr, "General Options:\n\t" \
"-a, --about\t\tshow information about %s\n\t" \
"-h, --help\t\tshow this help\n\t" \
"-v, --version\t\tshow version number\n\n" \
"Program Behaviour:\n\t" \
"-oFILE, --output=FILE\toutput to specified file (can be repeated)\n\t" \
"-gFILE, --debug=FILE\toutput debug info to specified file\n\t" \
"-q, --quiet\t\tquiet mode (can be repeated)\n\t" \
"-dDELAY, --delay=DELAY\tsave the stream during DELAY seconds and exit\n\t" \
"-k, --trick\t\tattempt to trick recalcitrant servers\n\t" \
"-t, --test\t\ttest mode (check stream availability)\n\n", PROGRAM_SHORT_NAME );
#else
fprintf ( stderr, "General Options:\n\t" \
"-a\tshow information about %s\n\t" \
"-h\tshow this help\n\t" \
"-v\tshow version number\n\n" \
"Program Behaviour:\n\t" \
"-oFILE\toutput to specified file (can be repeated)\n\t" \
"-gFILE\toutput debug info to specified file\n\t" \
"-q\tquiet mode (can be repeated)\n\t" \
"-dDELAY\tsave the stream during DELAY seconds and exit\n\t" \
"-k\tattempt to trick recalcitrant servers\n\t" \
"-t\ttest mode (check stream availability)\n\n", PROGRAM_SHORT_NAME );
#endif
return;
}
/*
* main
*/
int
main ( int argc,
char *argv[] )
{
MMS *mms;
FILE *f;
FILE *stddebug = NULL;
char *output_filename;
STREAM_LIST *stream_list;
STREAM_LIST *block;
char c;
int ret = MMS_RET_SUCCESS;
int quiet = 0;
int trick = MMS_TRICK_DISABLED;
int retry = 0;
int test = 0;
int delay = 0;
time_t end = 0;
float speed = 0.0f;
struct timeval speed_last_update;
struct timeval now;
float elapsed_time;
ssize_t len_written;
uint64_t total_len_written = 0;
uint64_t old_total_len_written = 0;
if ( ( stream_list = (STREAM_LIST *) malloc(sizeof(STREAM_LIST)) ) == NULL )
{
error ( "main", "early initialization failed" );
return 1;
}
stream_list->next = NULL;
stream_list->stream = NULL;
stream_list->output = NULL;
block = stream_list;
#ifdef HAVE_GETOPT_LONG
while ( ( c = getopt_long(argc, argv, options, long_options, NULL) ) != -1 )
#elif defined(SOLARIS) || defined(sun)
/* Implementation of getopt in Solaris is a bit strange, it returns -1 even if there are still args to parse... */
while ( optind < argc )
#else
while ( ( c = getopt(argc, argv, options) ) != -1 )
#endif
{
#if defined(SOLARIS) || defined(sun)
c = getopt ( argc, argv, options );
#endif
switch (c)
{
case 'h':
{
fprintf ( stderr, "\n" );
usage();
return 0;
}
case 'v':
{
fprintf ( stderr, "%s version %s\n", PROGRAM_SHORT_NAME, PROGRAM_VERSION);
return 0;
}
case 'a':
{
fprintf ( stderr, "\n" );
fprintf ( stderr, "%s (%s) version %s\n\n", PROGRAM_SHORT_NAME, PROGRAM_FULL_NAME, PROGRAM_VERSION);
fprintf ( stderr, "Written by %s.\n", PROGRAM_AUTHORS );
fprintf ( stderr, "With a lot of help from %s.\n\n", PROGRAM_HELPERS );
fprintf ( stderr, "This program is free software; you can redistribute it and/or\nmodify it under the terms " \
"of the GNU General Public License\nas published by the Free Software Foundation; either version 3" \
",\nor (at your option) any later version.\n\n" );
return 0;
}
case 't':
{
test = 1;
break;
}
case 'q':
{
quiet += 1;
break;
}
case 'k':
{
trick = MMS_TRICK_ENABLED;
break;
}
case 'o':
{
if ( optarg != NULL )
{
if ( block->stream != NULL )
{
if ( ( block->next = malloc ( sizeof(STREAM_LIST) ) ) == NULL )
{
error ( "main", "early initialization failed" );
ret = MMS_RET_ERROR;
goto clean;
}
block = block->next;
block->next = NULL;
block->stream = NULL;
}
if ( block->output != NULL )
free ( block->output );
block->output = (char *) strdup ( optarg );
}
break;
}
case 'g':
{
if ( optarg != NULL )
{
if ( stddebug != NULL )
fclose ( stddebug );
if ( ( stddebug = fopen ( optarg, "w" ) ) == NULL )
{
if ( quiet < 2 )
#ifdef HAVE_VSNPRINTF
warning ( NULL, "unable to write debug info in \'%s\'", optarg );
#else
warning ( NULL, "unable to write debug info in specified file" );
#endif
}
else
{
fprintf ( stddebug, "%s (%s) version %s\n\n", PROGRAM_SHORT_NAME, PROGRAM_FULL_NAME, PROGRAM_VERSION);
fprintf ( stddebug, "--> debug log begins now\n" );
}
}
break;
}
case 'd':
{
if ( optarg != NULL )
{
delay = atoi( optarg );
if ( delay < 0 )
delay = 0;
}
break;
}
#if defined(SOLARIS) || defined(sun)
case -1:
{
if ( optind >= argc )
break;
#else
case 1:
{
if ( optarg != NULL )
{
#endif
if ( block->stream != NULL )
{
if ( ( block->next = malloc ( sizeof(STREAM_LIST) ) ) == NULL )
{
error ( "main", "early initialization failed" );
ret = MMS_RET_ERROR;
goto clean;
}
block = block->next;
block->next = NULL;
block->output = NULL;
}
#if defined(SOLARIS) || defined(sun)
/* optind is not incremented when meeting something else than an option, so we do that... */
block->stream = (char *) strdup ( argv[optind++] );
#else
block->stream = (char *) strdup ( optarg );
}
#endif
break;
}
}
}
if ( stream_list->stream == NULL )
{
usage ( );
ret = MMS_RET_ERROR;
goto clean;
}
if ( !quiet )
{
fprintf ( stderr, "\n" );
fprintf ( stderr, "%s (%s) version %s\n\n", PROGRAM_SHORT_NAME, PROGRAM_FULL_NAME, PROGRAM_VERSION );
}
for ( block=stream_list; block!=NULL; block=(STREAM_LIST*)block->next )
{
if ( block->stream == NULL )
{
if ( quiet < 2 )
{
if ( block->output == NULL )
#ifdef HAVE_VSNPRINTF
error ( "main", "invalid invocation of %s", PROGRAM_SHORT_NAME );
#else
error ( "main", "invalid invocation of mmsrip" );
#endif
else
#ifdef HAVE_VSNPRINTF
error ( "main", "output to \'%s\' is not attached to any stream", block->output );
#else
error ( "main", "one of the -o output is not attached to any stream" );
#endif
}
ret = MMS_RET_ERROR;
goto clean;
}
if ( block->output == NULL )
{
char *tmp = strchr ( block->stream, '/' );
char *interro_ptr = strchr ( block->stream, '?' );
if ( interro_ptr == NULL )
output_filename = strrchr ( block->stream, '/' );
else
{
do /* we look for the last '/' before the first '?' */
{
output_filename = tmp;
tmp = strchr ( tmp+1, '/' );
}
while ( ( tmp < interro_ptr ) && ( tmp != NULL ) );
}
if ( output_filename == NULL )
{
if ( quiet < 2 )
#ifdef HAVE_VSNPRINTF
error ( "main", "malformed url: \'%s\'", block->stream );
#else
error ( "main", "malformed url" );
#endif
ret = MMS_RET_ERROR;
continue;
}
++output_filename;
if ( strlen ( output_filename ) == 0 )
{
if ( quiet < 2 )
#ifdef HAVE_VSNPRINTF
error ( "main", "malformed url: \'%s\'", block->stream );
#else
error ( "main", "malformed url" );
#endif
ret = MMS_RET_ERROR;
continue;
}
block->output = (char *) strdup ( output_filename );
/* we clean filenames that look like 'stream.asf?digest=7Q2bjXo&provider=lala' */
if ( ( interro_ptr = strchr(block->output,'?') ) != NULL )
*interro_ptr = '\0';
}
}
if ( ret != MMS_RET_SUCCESS )
goto clean;
if ( delay != 0 )
end = time(NULL) + delay;
for ( block=stream_list; block!=NULL; block=(STREAM_LIST*)(retry?block:block->next) )
{
output_filename = block->output;
retry = 0;
if ( !test )
{
if ( ( f = fopen ( output_filename, "w" ) ) == NULL )
{
if ( quiet < 2 )
#ifdef HAVE_VSNPRINTF
error ( "main", "unable to write in \'%s\'", output_filename );
#else
error ( "main", "unable to write in output file" );
#endif
ret = MMS_RET_ERROR;
continue;
}
}
else
f = NULL;
if ( ( mms = mms_create ( block->stream, f, stddebug, trick, test?1:(quiet>>1) ) ) == NULL )
{
if ( quiet < 2 )
error ( "main", "unable to create mms struct" );
if ( !test )
{
fclose ( f );
remove ( output_filename );
}
ret = MMS_RET_ERROR;
continue;
}
if ( !quiet )
fprintf ( stderr, "Connecting ...\r" );
if ( mms_connect ( mms ) != MMS_RET_SUCCESS )
{
if ( quiet < 2 )
error ( "main", "unable to connect" );
mms_destroy ( mms );
if ( !test )
{
fclose ( f );
remove ( output_filename );
}
ret = MMS_RET_ERROR;
continue;
}
if ( !quiet )
fprintf ( stderr, "Handshaking ...\r" );
if ( mms_handshake ( mms ) != MMS_RET_SUCCESS )
{
if ( ( quiet < 2 ) && ( !test ) )
error ( "main", "unable to handshake" );
mms_disconnect ( mms );
mms_destroy ( mms );
if ( !test )
{
fclose ( f );
remove ( output_filename );
}
if ( !quiet )
{
if ( !test )
fprintf ( stderr, "Stream \'%s\' is not good.\n\n", block->stream );
else
fprintf ( stderr, "Stream \'%s\' is not good.\n", block->stream );
}
ret = MMS_RET_ERROR;
continue;
}
if ( test )
{
if ( !quiet )
fprintf ( stderr, "Stream \'%s\' is available.\n", block->stream );
mms_disconnect ( mms );
mms_destroy ( mms );
continue;
}
if ( !quiet )
fprintf ( stderr, "Getting header ...\r" );
if ( ( len_written = mms_write_stream_header ( mms ) ) == MMS_RET_ERROR )
{
if ( quiet < 2 )
error ( "main", "unable to write stream header" );
mms_disconnect ( mms );
mms_destroy ( mms );
fclose ( f );
remove ( output_filename );
ret = MMS_RET_ERROR;
continue;
}
total_len_written = len_written;
if ( !quiet )
fprintf ( stderr, "Rip is about to start ...\r" );
if ( mms_begin_rip ( mms ) != MMS_RET_SUCCESS )
{
if ( quiet < 2 )
error ( "main", "unable to begin the rip" );
mms_disconnect ( mms );
mms_destroy ( mms );
fclose ( f );
remove ( output_filename );
ret = -1;
continue;
}
if ( mms->is_live == MMS_LIVE )
{
if ( !quiet )
{
fprintf ( stderr, " \r" );
fprintf ( stderr, "%s: %d bytes written (--.- kbps)\r", output_filename, (ssize_t)total_len_written );
gettimeofday ( &speed_last_update, NULL );
}
while ( 1 )
{
len_written = mms_write_stream_data ( mms );
if ( len_written == 0 )
break;
else if ( len_written == MMS_RET_ERROR )
{
if ( quiet < 2 )
error ( "main", "unable to write stream data" );
ret = MMS_RET_ERROR;
break;
}
else if ( len_written == MMS_RET_NO_AUTH )
{
if ( trick == MMS_TRICK_DISABLED )
{
/* we retry with the trick enabled */
if ( quiet < 2 )
fprintf ( stderr, "\r*** retrying with the anti-recalcitrant servers trick enabled ***\n" );
trick = MMS_TRICK_ENABLED;
retry = 1;
}
else
{
/* it's definitely not working */
if ( quiet < 2 )
error ( "main", "unable to write stream data" );
ret = MMS_RET_NO_AUTH;
}
break;
}
total_len_written += len_written;
if ( !quiet )
{
gettimeofday ( &now, NULL );
if ( now.tv_sec > speed_last_update.tv_sec )
{
elapsed_time = (now.tv_sec - speed_last_update.tv_sec) + ((now.tv_usec - speed_last_update.tv_usec) / 1000000.0f);
if ( elapsed_time >= 1.0f )
{
speed = ( ( ((float) (total_len_written-old_total_len_written)) / elapsed_time) / 1024.0f );
old_total_len_written = total_len_written;
gettimeofday ( &speed_last_update, NULL );
}
}
if ( speed > 0.0f )
{
if ( (speed / 1024.0f) >= 1.0f )
fprintf ( stderr, "%s: %d bytes written (%.1f mbps) \r", output_filename, (ssize_t)total_len_written, speed/1024.0f );
else
fprintf ( stderr, "%s: %d bytes written (%.1f kbps) \r", output_filename, (ssize_t)total_len_written, speed );
}
else
fprintf ( stderr, "%s: %d bytes written (--.- kbps) \r", output_filename, (ssize_t)total_len_written );
}
fflush ( f );
if ( delay != 0 )
{
if ( end <= time(NULL) )
{
delay = -1;
break;
}
}
}
/* for a live, we should rewrite the header */
if ( ( ret == MMS_RET_SUCCESS ) && ( !quiet ) && ( !retry ) )
fprintf ( stderr, "%s: %d bytes written \r", output_filename, (ssize_t)total_len_written );
}
else
{
register const double coef = 100.0 / (double) mms->expected_file_size;
if ( !quiet )
{
fprintf ( stderr, " \r" );
fprintf ( stderr, "%s: %.2f%% (--.- kbps)\r", output_filename, (double) total_len_written * coef );
gettimeofday ( &speed_last_update, NULL );
}
while ( 1 )
{
len_written = mms_write_stream_data ( mms );
if ( len_written == 0 )
break;
else if ( len_written == MMS_RET_ERROR )
{
if ( quiet < 2 )
error ( "main", "unable to write stream data" );
ret = MMS_RET_ERROR;
break;
}
else if ( len_written == MMS_RET_NO_AUTH )
{
if ( trick == MMS_TRICK_DISABLED )
{
/* we retry with the trick enabled */
if ( quiet < 2 )
fprintf ( stderr, "\r*** retrying with the anti-recalcitrant servers trick enabled ***\n" );
trick = MMS_TRICK_ENABLED;
retry = 1;
}
else
{
/* it's definitely not working */
if ( quiet < 2 )
error ( "main", "unable to write stream data" );
ret = MMS_RET_NO_AUTH;
}
break;
}
total_len_written += len_written;
if ( !quiet )
{
gettimeofday ( &now, NULL );
if ( now.tv_sec > speed_last_update.tv_sec )
{
elapsed_time = (now.tv_sec - speed_last_update.tv_sec) + ((now.tv_usec - speed_last_update.tv_usec) / 1000000.0f);
if ( elapsed_time >= 1.0f )
{
speed = ( ( ((float) (total_len_written-old_total_len_written)) / elapsed_time) / 1024.0f );
old_total_len_written = total_len_written;
gettimeofday ( &speed_last_update, NULL );
}
}
if ( speed > 0.0f )
{
if ( (speed / 1024.0f) >= 1.0f )
fprintf ( stderr, "%s: %.2f%% (%.1f mbps) \r", output_filename, (double) total_len_written * coef, speed/1024.0f );
else
fprintf ( stderr, "%s: %.2f%% (%.1f kbps) \r", output_filename, (double) total_len_written * coef, speed );
}
else
fprintf ( stderr, "%s: %.2f%% (--.- kbps) \r", output_filename, (double) total_len_written * coef );
}
fflush ( f );
if ( delay != 0 )
{
if ( end <= time(NULL) )
{
delay = -1;
break;
}
}
}
if ( ( ret == MMS_RET_SUCCESS ) && ( !quiet ) && ( delay != -1 ) && ( !retry ) )
fprintf ( stderr, "%s: 100.00%% \r", output_filename );
}
mms_disconnect ( mms );
mms_destroy ( mms );
fclose ( f );
if ( delay == -1 )
break;
}
clean:
if ( !quiet )
fprintf ( stderr, "\n" );
if ( stddebug != NULL )
{
fprintf ( stddebug, "\n\n--> debug log ends now\n" );
fclose ( stddebug );
}
for ( block=stream_list; block!=NULL; )
{
STREAM_LIST *old;
old = block;
block = (STREAM_LIST *) block->next;
if ( old->stream != NULL )
free ( old->stream );
if ( old->output != NULL )
free ( old->output );
free ( old );
}
return (ret<0) ? (ret*-1) : ret;
}

1239
src/mmsrip/mms.c Normal file

File diff suppressed because it is too large Load Diff

131
src/mmsrip/mms.h Normal file
View File

@@ -0,0 +1,131 @@
/*
* $RCSfile: mms.h,v $
* $Date: 2006/01/23 20:30:43 $ - $Revision: 1.17 $
*
* This file is distributed as a part of MMSRIP ( MMS Ripper ).
* Copyright (c) 2005-2006 Nicolas BENOIT
*
* It is highly based on the work of SDP Multimedia and Major MMS.
* They deserve all the credits for it.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __MMS_H__
#define __MMS_H__
#include "common.h"
#ifdef _WIN32
typedef signed long int ssize_t;
#define bcopy(s, d, l) memcpy(d, s, l)
#include <assert.h>
#define close closesocket
#define read(soc, data, len) recv(soc, data, len, 0)
#define write(soc, data, len) send(soc, data, len, 0)
#define SHUT_RDWR SD_BOTH
#endif
#if defined(__CYGWIN__) || defined(_WIN32)
typedef unsigned char uint8_t;
#ifndef __uint32_t_defined
#define __uint32_t_defined
typedef unsigned int uint32_t;
#endif
typedef unsigned long long int uint64_t;
#else
#if defined(SOLARIS) || defined(sun)|| defined (__FreeBSD__) || defined(HAVE_INTTYPES_H)
#include <inttypes.h>
#else
#include <stdint.h>
#endif
#endif
#define MMS_SERVER 0
#define MMS_CLIENT 1
#define MMS_NO_LIVE 0
#define MMS_LIVE 1
#define MMS_WMV 0
#define MMS_ASF 1
#define MMS_TRICK_DISABLED 0
#define MMS_TRICK_ENABLED 1
#define MMS_CMD_INVALID -1
#define MMS_CMD_HELLO 0x01
#define MMS_CMD_PROTOCOL_SELECT 0x02
#define MMS_CMD_FILE_REQUEST 0x05
#define MMS_CMD_READY_TO_STREAM 0x05
#define MMS_CMD_STREAM_INFOS 0x06
#define MMS_CMD_START_PACKET 0x07
#define MMS_CMD_STOP_STREAM 0x09
#define MMS_CMD_BYE_BYE 0x0D
#define MMS_CMD_HEADER_DATA 0x11
#define MMS_CMD_HEADER_REQUEST 0x15
#define MMS_CMD_NET_TESTING 0x15
#define MMS_CMD_PING 0x1B
#define MMS_CMD_PONG 0x1B
#define MMS_CMD_END_OF_STREAM 0x1E
#define MMS_CMD_STREAM_SELECT_ACK 0x21
#define MMS_CMD_STREAM_SELECT 0x33
#define MMS_RET_SUCCESS 0
#define MMS_RET_ERROR -1
#define MMS_RET_NO_AUTH -2
#define MMS_RET_ACKED -3
#define MMS_BUF_SIZE 102400
typedef struct
{
uint8_t buf[MMS_BUF_SIZE];
int num_bytes;
} MMS_PACKET ;
typedef struct
{
char *host;
char *path;
int socket;
FILE *out;
FILE *stddebug;
ssize_t media_packet_len;
uint64_t expected_file_size;
int is_live;
int stream_type;
int seq_num;
int num_stream_ids;
int stream_ids[20];
int quiet;
int trick;
} MMS ;
MMS * mms_create ( const char *, FILE *, FILE *, const int, const int );
int mms_connect ( MMS* );
int mms_handshake ( MMS * );
ssize_t mms_write_stream_header ( MMS * );
int mms_begin_rip ( MMS * );
ssize_t mms_write_stream_data ( MMS * );
void mms_disconnect ( MMS * );
void mms_destroy ( MMS * );
#endif

View File

@@ -1,127 +0,0 @@
//-----------------------------------------------------------------------------
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
// Note - The x86 and x64 versions do _not_ produce the same results, as the
// algorithms are optimized for their respective platforms. You can still
// compile and run any of them on any platform, but your performance with the
// non-native version will be less than optimal.
#include <stdint.h>
static uint32_t rotl32 ( uint32_t x, int8_t r )
{
return (x << r) | (x >> (32 - r));
}
#define ROTL32(x,y) rotl32(x,y)
static uint32_t getblock32 ( const uint32_t * p, int i )
{
return p[i];
}
static uint32_t fmix32 ( uint32_t h )
{
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
#define BIG_CONSTANT(x) (x##LLU)
static void MurmurHash3_x86_128 ( const void * key, const int len,
uint32_t seed, void * out ) {
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 16;
uint32_t h1 = seed;
uint32_t h2 = seed;
uint32_t h3 = seed;
uint32_t h4 = seed;
const uint32_t c1 = 0x239b961b;
const uint32_t c2 = 0xab0e9789;
const uint32_t c3 = 0x38b34ae5;
const uint32_t c4 = 0xa1e38b93;
const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
int i;
for(i = -nblocks; i; i++)
{
uint32_t k1 = getblock32(blocks,i*4+0);
uint32_t k2 = getblock32(blocks,i*4+1);
uint32_t k3 = getblock32(blocks,i*4+2);
uint32_t k4 = getblock32(blocks,i*4+3);
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
}
{
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
uint32_t k1 = 0;
uint32_t k2 = 0;
uint32_t k3 = 0;
uint32_t k4 = 0;
switch(len & 15)
{
case 15: k4 ^= tail[14] << 16;
case 14: k4 ^= tail[13] << 8;
case 13: k4 ^= tail[12] << 0;
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
case 12: k3 ^= tail[11] << 24;
case 11: k3 ^= tail[10] << 16;
case 10: k3 ^= tail[ 9] << 8;
case 9: k3 ^= tail[ 8] << 0;
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
case 8: k2 ^= tail[ 7] << 24;
case 7: k2 ^= tail[ 6] << 16;
case 6: k2 ^= tail[ 5] << 8;
case 5: k2 ^= tail[ 4] << 0;
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
case 4: k1 ^= tail[ 3] << 24;
case 3: k1 ^= tail[ 2] << 16;
case 2: k1 ^= tail[ 1] << 8;
case 1: k1 ^= tail[ 0] << 0;
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
h1 = fmix32(h1);
h2 = fmix32(h2);
h3 = fmix32(h3);
h4 = fmix32(h4);
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
((uint32_t*)out)[0] = h1;
((uint32_t*)out)[1] = h2;
((uint32_t*)out)[2] = h3;
((uint32_t*)out)[3] = h4;
}
}

View File

@@ -175,6 +175,8 @@ HTS_UNUSED static const char *jump_protocol(const char *source) {
source += p;
else if ((p = strfield(source, "file:")))
source += p;
else if ((p = strfield(source, "mms:")))
source += p;
// net_path
if (strncmp(source, "//", 2) == 0)
source += 2;

View File

@@ -30,9 +30,6 @@ Please visit our Website: http://www.httrack.com
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef __ANDROID__
static long int timezone = 0;
#endif
/* Locking */
#ifdef _WIN32
@@ -236,7 +233,7 @@ struct _PT_Cache {
PT_Indexes PT_New(void) {
PT_Indexes index = (PT_Indexes) calloc(sizeof(_PT_Indexes), 1);
index->cil = inthash_new(0);
index->cil = inthash_new(127);
index->index_size = 0;
index->index = NULL;
return index;
@@ -434,7 +431,7 @@ char **PT_Enumerate(PT_Indexes indexes, const char *url, int subtree) {
inthash hdupes = NULL;
if (!subtree)
hdupes = inthash_new(0);
hdupes = inthash_new(127);
StringClear(list);
StringClear(listindexes);
StringClear(subitem);
@@ -551,7 +548,7 @@ PT_Index PT_LoadCache(const char *filename) {
index->type = type;
index->slots.common.timestamp = (time_t) time(NULL);
index->slots.common.startUrl[0] = '\0';
index->slots.common.hash = inthash_new(0);
index->slots.common.hash = inthash_new(8191);
if (!_IndexFuncts[type].PT_LoadCache(index, filename)) {
proxytrack_print_log(DEBUG,
"reading httrack cache (format #%d) %s : error",

View File

@@ -1,5 +0,0 @@
#!/bin/bash
#
# httrack internal hashtable autotest on 100K keys
httrack -#7 100000

View File

@@ -8,6 +8,6 @@ TESTS_ENVIRONMENT += ONLINE_UNIT_TESTS=$(ONLINE_UNIT_TESTS)
TESTS_ENVIRONMENT += HTTPS_SUPPORT=$(HTTPS_SUPPORT)
TEST_EXTENSIONS = .test
TESTS = 00_runnable.test 01_engine-charset.test 01_engine-entities.test 01_engine-hashtable.test 01_engine-idna.test 01_engine-simplify.test 10_crawl-simple.test 11_crawl-cookies.test 11_crawl-idna.test 11_crawl-international.test 11_crawl-parsing.test 12_crawl_https.test
TESTS = 00_runnable.test 01_engine-charset.test 01_engine-entities.test 01_engine-idna.test 01_engine-simplify.test 10_crawl-simple.test 11_crawl-cookies.test 11_crawl-idna.test 11_crawl-international.test 11_crawl-parsing.test 12_crawl_https.test
CLEANFILES = check-network_sh.cache

View File

@@ -214,7 +214,7 @@ TESTS_ENVIRONMENT = PATH=$(top_builddir)/src$(PATH_SEPARATOR)$$PATH \
ONLINE_UNIT_TESTS=$(ONLINE_UNIT_TESTS) \
HTTPS_SUPPORT=$(HTTPS_SUPPORT)
TEST_EXTENSIONS = .test
TESTS = 00_runnable.test 01_engine-charset.test 01_engine-entities.test 01_engine-hashtable.test 01_engine-idna.test 01_engine-simplify.test 10_crawl-simple.test 11_crawl-cookies.test 11_crawl-idna.test 11_crawl-international.test 11_crawl-parsing.test 12_crawl_https.test
TESTS = 00_runnable.test 01_engine-charset.test 01_engine-entities.test 01_engine-idna.test 01_engine-simplify.test 10_crawl-simple.test 11_crawl-cookies.test 11_crawl-idna.test 11_crawl-international.test 11_crawl-parsing.test 12_crawl_https.test
CLEANFILES = check-network_sh.cache
all: all-am