diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c8828692..881ccc6b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,12 @@ if(OPENSSL_FOUND) endif() endif() +find_package(CURL REQUIRED) +# Add libcurl include directories +target_include_directories(WALLET_A ${CURL_INCLUDE_DIRS}) +# Link against libcurl +target_link_libraries(WALLET_A ${CURL_LIBRARIES}) + find_package(LibEvent REQUIRED) find_package(GMP) diff --git a/configure.ac b/configure.ac index 7e4f501c7..87ba6d475 100644 --- a/configure.ac +++ b/configure.ac @@ -3,10 +3,10 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 1) define(_CLIENT_VERSION_MINOR, 5) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 1) +define(_CLIENT_VERSION_BUILD, 2) define(_CLIENT_VERSION_RC, 0) define(_CLIENT_VERSION_IS_RELEASE, true) -define(_COPYRIGHT_YEAR, 2021) +define(_COPYRIGHT_YEAR, 2024) AC_INIT([Sapphire Core],m4_join([.], _CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MINOR, _CLIENT_VERSION_REVISION, m4_if(_CLIENT_VERSION_BUILD, [0], [], _CLIENT_VERSION_BUILD))m4_if(_CLIENT_VERSION_RC, [0], [], [rc]_CLIENT_VERSION_RC),[https://github.com/decenomy/SAPP/issues],[sapphire],[https://sappcoin.com/]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/pivx-config.h]) @@ -18,6 +18,8 @@ BITCOIN_GUI_NAME=sapphire-qt BITCOIN_CLI_NAME=sapphire-cli BITCOIN_TX_NAME=sapphire-tx +BOOTSTRAP_URL_DEFAULT=https://bootstraps.decenomy.net/ + dnl Unless the user specified ARFLAGS, force it to be cr AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to if not set]) if test "x${ARFLAGS+set}" != "xset"; then @@ -113,6 +115,13 @@ AC_ARG_WITH([params-dir], ], [params_path=""]) +# Allow the user to specify a different value for BOOTSTRAP_URL +AC_ARG_WITH([bootstrap-url], + [AS_HELP_STRING([--with-bootstrap-url=URL], + [URL for bootstrap data])], + [BOOTSTRAP_URL="$withval"], + [BOOTSTRAP_URL="$BOOTSTRAP_URL_DEFAULT"]) + # Enable wallet AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--disable-wallet], @@ -120,6 +129,13 @@ AC_ARG_ENABLE([wallet], [enable_wallet=$enableval], [enable_wallet=yes]) +# Enable bootstrap +AC_ARG_ENABLE([bootstrap], + [AS_HELP_STRING([--disable-bootstrap], + [disable bootstrap (enabled by default)])], + [enable_bootstrap=$enableval], + [enable_bootstrap=yes]) + AC_ARG_WITH([miniupnpc], [AS_HELP_STRING([--with-miniupnpc], [enable UPNP (default is yes if libminiupnpc is found)])], @@ -501,6 +517,12 @@ case $host in AC_MSG_ERROR("windres not found") fi + # Check for curl-config + AC_PATH_PROG([CURL_CONFIG], [curl-config], none, [$prefix/bin]) + if test x$CURL_CONFIG = xnone; then + AC_MSG_ERROR("curl-config not found") + fi + CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB" if test "x$CXXFLAGS_overridden" = "xno"; then CXXFLAGS="$CXXFLAGS -w" @@ -1056,6 +1078,8 @@ if test x$use_pkgconfig = xyes; then PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)]) BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])]) + PKG_CHECK_MODULES([CURL], [libcurl],, [AC_MSG_ERROR(curl not found.)]) + PKG_CHECK_MODULES([ZLIB], [zlib],, [AC_MSG_ERROR(zlib not found.)]) BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode],,[BITCOIN_QT_FAIL(libqrencode not found)])]) if test x$use_qtcharts != xno; then BITCOIN_QT_CHECK([PKG_CHECK_MODULES([CHARTS], [Qt5Charts],[have_qtcharts=yes], [have_qtcharts=no])]) @@ -1077,6 +1101,7 @@ if test x$use_pkgconfig = xyes; then else AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) fi + ] ) else @@ -1119,6 +1144,20 @@ else BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found))) + AC_CHECK_HEADER([curl/curl.h],, AC_MSG_ERROR(curl headers missing),) + AC_CHECK_LIB([curl] ,[main],[CURL_LIBS=-lcurl], AC_MSG_ERROR(curl not found)) + + # Use curl-config to get libcurl flags and add -DCURL_STATICLIB to CURL_CFLAGS + if test "x$CURL_CONFIG" != "xnone"; then + CURL_CONFIG_CFLAGS=`$CURL_CONFIG --cflags` + CURL_CFLAGS="$CURL_CFLAGS -DCURL_STATICLIB $CURL_CONFIG_CFLAGS" + CURL_CONFIG_LIBS=`$CURL_CONFIG --libs` + CURL_LIBS="$CURL_LIBS $CURL_CONFIG_LIBS" + fi + + AC_CHECK_HEADER([zlib.h],, AC_MSG_ERROR(zlib headers missing),) + AC_CHECK_LIB([z] ,[main],[ZLIB_LIBS=-lz], AC_MSG_ERROR(zlib not found)) + BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], BITCOIN_QT_FAIL(libqrencode not found))]) BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, BITCOIN_QT_FAIL(libqrencode not found))]) if test x$use_qtcharts != xno; then @@ -1228,6 +1267,16 @@ else AC_MSG_RESULT(no) fi +dnl enable bootstrap +AC_MSG_CHECKING([if bootstrap should be enabled]) +if test x$enable_bootstrap != xno; then + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED([ENABLE_BOOTSTRAP],[1],[Define to 1 to enable bootstrap functions]) + +else + AC_MSG_RESULT(no) +fi + dnl enable upnp support AC_MSG_CHECKING([whether to build with support for UPnP]) if test x$have_miniupnpc = xno; then @@ -1322,6 +1371,7 @@ AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin]) AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows]) AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes]) +AM_CONDITIONAL([ENABLE_BOOTSTRAP],[test x$enable_bootstrap = xyes]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes]) AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$BUILD_TEST_QT = xyes]) @@ -1346,6 +1396,7 @@ AC_DEFINE(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD, [Version Build]) AC_DEFINE(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE, [Version is release]) AC_DEFINE(COPYRIGHT_YEAR, _COPYRIGHT_YEAR, [Version is release]) AC_DEFINE_UNQUOTED(PARAMS_DIR, ["$params_path"], [Path to the zk params dir during unit tests on windows]) +AC_DEFINE_UNQUOTED([BOOTSTRAP_URL], ["$BOOTSTRAP_URL"], [URL for bootstrap data]) AC_SUBST(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR) AC_SUBST(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR) AC_SUBST(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION) @@ -1391,6 +1442,8 @@ AC_SUBST(EVENT_LIBS) AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(ZMQ_LIBS) AC_SUBST(PROTOBUF_LIBS) +AC_SUBST(CURL_LIBS) +AC_SUBST(ZLIB_LIBS) AC_SUBST(QR_LIBS) AC_SUBST(USE_NUM_GMP) AC_SUBST(USE_NUM_OPENSSL) @@ -1462,37 +1515,39 @@ esac echo echo "Options used to compile and link:" -echo " with wallet = $enable_wallet" -echo " with gui / qt = $bitcoin_enable_qt" +echo " with wallet = $enable_wallet" +echo " with bootstrap = $enable_bootstrap" +echo " bootstrap url = $BOOTSTRAP_URL" +echo " with gui / qt = $bitcoin_enable_qt" if test x$bitcoin_enable_qt != xno; then echo " with qtcharts = $use_qtcharts" fi -echo " with zmq = $use_zmq" -echo " with test = $use_tests" -echo " with bench = $use_bench" -echo " with upnp = $use_upnp" -echo " with params = $params_path" -echo " use asm = $use_asm" -echo " sanitizers = $use_sanitizers" -echo " debug enabled = $enable_debug" -echo " gprof enabled = $enable_gprof" -echo " werror = $enable_werror" -echo " host = $host" +echo " with zmq = $use_zmq" +echo " with test = $use_tests" +echo " with bench = $use_bench" +echo " with upnp = $use_upnp" +echo " with params = $params_path" +echo " use asm = $use_asm" +echo " sanitizers = $use_sanitizers" +echo " debug enabled = $enable_debug" +echo " gprof enabled = $enable_gprof" +echo " werror = $enable_werror" +echo " host = $host" echo -echo " target os = $TARGET_OS" -echo " build os = $BUILD_OS" +echo " target os = $TARGET_OS" +echo " build os = $BUILD_OS" echo -echo " CC = $CC" -echo " CFLAGS = $CFLAGS" -echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CPPFLAGS" -echo " CXX = $CXX" -echo " CXXFLAGS = $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" -echo " LDFLAGS = $PTHREAD_CFLAGS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" -echo " ARFLAGS = $ARFLAGS" -echo " PIC_FLAGS = $PIC_FLAGS" -echo " QT_PIE_FLAGS = $QT_PIE_FLAGS" -echo " SVG_LIBS = $QT_SVG_LIBS " -echo " SVG_CFLAGS = $QT_SVG_INCLUDES " -echo " CHARTS_LIBS = $CHARTS_LIBS " -echo " CHARTS_CFLAGS = $CHARTS_CFLAGS " +echo " CC = $CC" +echo " CFLAGS = $CFLAGS" +echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CPPFLAGS" +echo " CXX = $CXX" +echo " CXXFLAGS = $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" +echo " LDFLAGS = $PTHREAD_CFLAGS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" +echo " ARFLAGS = $ARFLAGS" +echo " PIC_FLAGS = $PIC_FLAGS" +echo " QT_PIE_FLAGS = $QT_PIE_FLAGS" +echo " SVG_LIBS = $QT_SVG_LIBS " +echo " SVG_CFLAGS = $QT_SVG_INCLUDES " +echo " CHARTS_LIBS = $CHARTS_LIBS " +echo " CHARTS_CFLAGS = $CHARTS_CFLAGS " echo diff --git a/contrib/docker/Dockerfile.dsw-develop-builder b/contrib/docker/Dockerfile.dsw-develop-builder new file mode 100644 index 000000000..8317f17d2 --- /dev/null +++ b/contrib/docker/Dockerfile.dsw-develop-builder @@ -0,0 +1,145 @@ +# Use a base image (Ubuntu 18.04) +# FROM ubuntu:18.04 +FROM ubuntu@sha256:dca176c9663a7ba4c1f0e710986f5a25e672842963d95b960191e2d9f7185ebe + +# Set arguments +ARG CPU_CORES=1 +ARG TARGET=develop + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV QT_RCC_TEST=1 +ENV QT_RCC_SOURCE_DATE_OVERRIDE=1 +ENV ZERO_AR_DATE=1 +ENV WRAP_DIR=/wrapped +ENV HOSTS="x86_64-linux-gnu aarch64-linux-gnu x86_64-apple-darwin14 x86_64-w64-mingw32" +ENV FAKETIME_HOST_PROGS="ar ranlib nm windres strip objcopy gcc g++" +ENV FAKETIME_PROGS="ar ranlib nm strip objcopy gcc g++ date zip wine wine64 dmg genisoimage tar" + + +# Update and install necessary packages +RUN dpkg --add-architecture i386 && \ + apt-get update && \ + apt-get install -y \ + curl=7.58.0-2ubuntu3.24 \ + git=1:2.17.1-1ubuntu0.18 \ + zip=3.0-11build1 \ + faketime=0.9.7-2 \ + build-essential=12.4ubuntu1 \ + libtool=2.4.6-2 \ + bsdmainutils=11.1.2ubuntu1 \ + autotools-dev=20180224.1 \ + autoconf=2.69-11 \ + pkg-config=0.29.1-0ubuntu2 \ + automake=1:1.15.1-3ubuntu2 \ + python3=3.6.7-1~18.04 \ + g++-aarch64-linux-gnu=4:7.4.0-1ubuntu2.3 \ + g++-8-aarch64-linux-gnu=8.4.0-1ubuntu1~18.04cross2 \ + gcc-8-aarch64-linux-gnu=8.4.0-1ubuntu1~18.04cross2 \ + binutils-aarch64-linux-gnu=2.30-21ubuntu1~18.04.9 \ + g++-8-multilib=8.4.0-1ubuntu1~18.04 \ + gcc-8-multilib=8.4.0-1ubuntu1~18.04 \ + python3-dev=3.6.7-1~18.04 \ + python3-setuptools=39.0.1-2ubuntu0.1 \ + fonts-tuffy=20120614-2 \ + libcap-dev=1:2.25-1.2 \ + libz-dev \ + libbz2-dev=1.0.6-8.1ubuntu0.2 \ + imagemagick=8:6.9.7.4+dfsg-16ubuntu6.15 \ + cmake=3.10.2-1ubuntu2.18.04.2 \ + librsvg2-bin=2.40.20-2ubuntu0.2 \ + libtiff-tools=4.0.9-5ubuntu0.10 \ + mingw-w64=5.0.3-1 \ + xvfb=2:1.19.6-1ubuntu4.15 \ + wine32=3.0-1ubuntu1 \ + wine64=3.0-1ubuntu1 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Set POSIX for x86_64-w64-mingw32-g++ alternatives config +RUN echo "1" | update-alternatives --config x86_64-w64-mingw32-g++ + +# use a fixed date +RUN echo -n "2000-01-01 12:00:00" > /git_timestamp +RUN echo -n "200001011200.00" > /git_timestamp_touch + +# Compile the depends folder using a deterministic timestamp + +RUN mkdir -p ${WRAP_DIR} + +RUN for prog in ${FAKETIME_PROGS}; \ + do \ + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog}; \ + echo -n "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1 " >> ${WRAP_DIR}/${prog}; \ + echo -n "FAKETIME=\"\$(cat /git_timestamp)\" " >> ${WRAP_DIR}/${prog}; \ + echo "\$(which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -n 1) \"\$@\"" >> ${WRAP_DIR}/${prog}; \ + chmod +x ${WRAP_DIR}/${prog}; \ + done + +RUN for host in $HOSTS; \ + do \ + for prog in ${FAKETIME_HOST_PROGS}; \ + do \ + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${host}-${prog}; \ + echo -n "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1 " >> ${WRAP_DIR}/${host}-${prog}; \ + echo -n "FAKETIME=\"\$(cat /git_timestamp)\" " >> ${WRAP_DIR}/${host}-${prog}; \ + echo "\$(which -a ${host}-${prog} | grep -v ${WRAP_DIR}/${host}-${prog} | head -n 1) \"\$@\"" >> ${WRAP_DIR}/${host}-${prog}; \ + chmod +x ${WRAP_DIR}/${host}-${prog}; \ + done \ + done + +# Clone the repository +RUN git clone https://github.com/decenomy/DSW.git + +WORKDIR /DSW + +# Check out a specific version if needed +RUN git checkout -B $TARGET +RUN git pull origin $TARGET + +# --- macos --- +# Install the MacOS SDK +RUN mkdir -p /DSW/depends/SDKs +WORKDIR /DSW/depends/SDKs + +RUN curl -LO https://github.com/decenomy/depends/raw/main/SDKs/MacOSX10.11.sdk.tar.xz +RUN touch -t $(cat /git_timestamp_touch) /DSW/depends/SDKs/MacOSX10.11.sdk.tar.xz +RUN PATH=${WRAP_DIR}:${PATH} tar -C /DSW/depends/SDKs -xf /DSW/depends/SDKs/MacOSX10.11.sdk.tar.xz +RUN rm /DSW/depends/SDKs/MacOSX10.11.sdk.tar.xz +# --- --- --- + +# --- windows --- +# Set the Inno Setup compiler +WORKDIR /DSW/contrib/innosetup + +ENV DISPLAY=:99 +RUN Xvfb :99 -screen 0 1024x768x16 -nolisten tcp & + +RUN Xvfb :99 -screen 0 1024x768x16 -nolisten tcp & \ + wine innosetup-6.1.2.exe /VERYSILENT /NORESTART /ALLUSERS /SUPPRESSMSGBOXES /SP /LOG=setup.log && \ + wine idpsetup-1.5.1.exe /VERYSILENT /NORESTART /ALLUSERS /SUPPRESSMSGBOXES /SP /LOG=setup.log + +RUN rm /tmp/.X99-lock +# --- --- --- + +# Switch to the repository directory +WORKDIR /DSW/depends + +# Builds the dependencies in the depends folder +RUN for host in $HOSTS; \ + do \ + PATH=${WRAP_DIR}:${PATH} make -j$(echo $CPU_CORES) HOST=${host}; \ + done + +# Set the work dir to the root folder +WORKDIR / + +# Set the entry point if you want to interact within the container +ENTRYPOINT ["bash"] + +# Build it with: +# docker build --build-arg CPU_CORES= --build-arg TARGET= -t decenomy/dsw-develop-builder -f Dockerfile.dsw-develop-builder . +# Publish with: +# docker login +# docker push decenomy/dsw-develop-builder:latest diff --git a/contrib/docker/Dockerfile.dsw-linux-arm64-builder b/contrib/docker/Dockerfile.dsw-linux-arm64-builder index 7d10bfd41..f9316ad25 100644 --- a/contrib/docker/Dockerfile.dsw-linux-arm64-builder +++ b/contrib/docker/Dockerfile.dsw-linux-arm64-builder @@ -14,14 +14,14 @@ ENV QT_RCC_SOURCE_DATE_OVERRIDE=1 # Update and install necessary packages RUN apt-get update && \ apt-get install -y \ - curl=7.58.0-2ubuntu3.24 \ + curl=7.58.0-2ubuntu3.24 \ git=1:2.17.1-1ubuntu0.18 \ zip=3.0-11build1 \ faketime=0.9.7-2 \ - build-essential=12.4ubuntu1 \ + build-essential=12.4ubuntu1 \ libtool=2.4.6-2 \ bsdmainutils=11.1.2ubuntu1 \ - autotools-dev=20180224.1 \ + autotools-dev=20180224.1 \ autoconf=2.69-11 \ pkg-config=0.29.1-0ubuntu2 \ automake=1:1.15.1-3ubuntu2 \ diff --git a/contrib/docker/Dockerfile.dsw-linux-arm64-wallet b/contrib/docker/Dockerfile.dsw-linux-arm64-wallet index d95b63645..bc9fd76f7 100644 --- a/contrib/docker/Dockerfile.dsw-linux-arm64-wallet +++ b/contrib/docker/Dockerfile.dsw-linux-arm64-wallet @@ -1,5 +1,5 @@ # FROM decenomy/dsw-linux-arm64-builder:latest -FROM decenomy/dsw-linux-arm64-builder@sha256:7e0c655c60175684cff89993cada14ce85544c636e25d75121a8ac8a3c169c19 +FROM decenomy/dsw-linux-arm64-builder@sha256:e687b911b160c600716dbd1d481f82e3d22c1fbe9cb035097552fe0504d1b78d # ARG for specifying the number of cores ARG CPU_CORES=1 @@ -11,13 +11,16 @@ ARG BASE_NAME=sapphire ARG TARGET=master # Clone the repository -RUN git clone https://github.com/decenomy/$TICKER +RUN if [ ! -d $TICKER ]; then \ + git clone https://github.com/decenomy/$TICKER; \ +fi # Switch to the repository directory WORKDIR /$TICKER # Check out a specific version if needed -RUN git checkout $TARGET +RUN git checkout -B $TARGET +RUN git pull origin $TARGET # Run Git commands to extract the timestamps RUN git log -1 --format="%at" | xargs -I{} date -d @{} "+%Y-%m-%d %H:%M:%S" > /git_timestamp @@ -43,9 +46,9 @@ RUN PATH=${WRAP_DIR}:${PATH} make -j$CPU_CORES HOST=aarch64-linux-gnu # Extract the wallet version RUN grep "define(_CLIENT_VERSION_MAJOR" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' > /wallet_version -RUN echo -n "." >> /wallet_version +RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_MINOR" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version -RUN echo -n "." >> /wallet_version +RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_REVISION" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_BUILD" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version @@ -66,7 +69,7 @@ RUN sha256sum $(echo $BASE_NAME)-tx >> SHA256SUMS-Linux-arm64.ASC RUN sha256sum $(echo $BASE_NAME)-qt >> SHA256SUMS-Linux-arm64.ASC RUN sha256sum $TICKER-$(cat /wallet_version)-Linux-arm64.zip >> SHA256SUMS-Linux-arm64.ASC -# To compile and build the container execute docker in this way: +# To compile and build the container execute docker in this way: # docker build \ # --build-arg CPU_CORES= \ # --build-arg TICKER= \ diff --git a/contrib/docker/Dockerfile.dsw-linux-x64-wallet b/contrib/docker/Dockerfile.dsw-linux-x64-wallet index 7570a0d73..dbba20a6d 100644 --- a/contrib/docker/Dockerfile.dsw-linux-x64-wallet +++ b/contrib/docker/Dockerfile.dsw-linux-x64-wallet @@ -1,5 +1,6 @@ # FROM decenomy/dsw-linux-x64-builder:latest -FROM decenomy/dsw-linux-x64-builder@sha256:5ea66af7cd196a294d3222c5013a3f2a1ac343238c603234f06f4d6b9725ff13 +FROM decenomy/dsw-linux-x64-builder@sha256:c1d14e04ce8f0ab32ed23d4c961faf0b7f3c3059d17fad895bccc6ce571d82e4 + # ARG for specifying the number of cores ARG CPU_CORES=1 @@ -11,13 +12,16 @@ ARG BASE_NAME=sapphire ARG TARGET=master # Clone the repository -RUN git clone https://github.com/decenomy/$TICKER +RUN if [ ! -d $TICKER ]; then \ + git clone https://github.com/decenomy/$TICKER; \ +fi # Switch to the repository directory WORKDIR /$TICKER # Check out a specific version if needed -RUN git checkout $TARGET +RUN git checkout -B $TARGET +RUN git pull origin $TARGET # Run Git commands to extract the timestamps RUN git log -1 --format="%at" | xargs -I{} date -d @{} "+%Y-%m-%d %H:%M:%S" > /git_timestamp @@ -43,9 +47,9 @@ RUN PATH=${WRAP_DIR}:${PATH} make -j$CPU_CORES HOST=x86_64-pc-linux-gnu # Extract the wallet version RUN grep "define(_CLIENT_VERSION_MAJOR" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' > /wallet_version -RUN echo -n "." >> /wallet_version +RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_MINOR" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version -RUN echo -n "." >> /wallet_version +RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_REVISION" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_BUILD" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version @@ -63,7 +67,7 @@ RUN sha256sum $(echo $BASE_NAME)-tx >> SHA256SUMS-Linux-x64.ASC RUN sha256sum $(echo $BASE_NAME)-qt >> SHA256SUMS-Linux-x64.ASC RUN sha256sum $TICKER-$(cat /wallet_version)-Linux-x64.zip >> SHA256SUMS-Linux-x64.ASC -# To compile and build the container execute docker in this way: +# To compile and build the container execute docker in this way: # docker build \ # --build-arg CPU_CORES= \ # --build-arg TICKER= \ diff --git a/contrib/docker/Dockerfile.dsw-macos-x64-wallet b/contrib/docker/Dockerfile.dsw-macos-x64-wallet index 3faf213ce..6c223f794 100644 --- a/contrib/docker/Dockerfile.dsw-macos-x64-wallet +++ b/contrib/docker/Dockerfile.dsw-macos-x64-wallet @@ -1,5 +1,5 @@ #FROM decenomy/dsw-macos-x64-builder:latest -FROM decenomy/dsw-macos-x64-builder@sha256:f939a1629656448566f303eff6ad0dfd79ae8bb136e937888063e8b3c90e0bc5 +FROM decenomy/dsw-macos-x64-builder@sha256:bdef2e446c09c7f601cc490841711e8f4ca47e4f81ba4306a8d2ace0b58012db # ARG for specifying the number of cores ARG CPU_CORES=1 @@ -11,13 +11,16 @@ ARG BASE_NAME=sapphire ARG TARGET=master # Clone the repository -RUN git clone https://github.com/decenomy/$TICKER +RUN if [ ! -d $TICKER ]; then \ + git clone https://github.com/decenomy/$TICKER; \ +fi # Switch to the repository directory WORKDIR /$TICKER # Check out a specific version if needed -RUN git checkout $TARGET +RUN git checkout -B $TARGET +RUN git pull origin $TARGET RUN git log -1 --format="%at" | xargs -I{} date -d @{} "+%Y-%m-%d %H:%M:%S" > /git_timestamp RUN git log -1 --format="%at" | xargs -I{} date -d @{} "+%Y%m%d%H%M.%S" > /git_timestamp_touch @@ -45,9 +48,9 @@ RUN PATH=${WRAP_DIR}:${PATH} make -j$CPU_CORES HOST=x86_64-apple-darwin14 # Extract the wallet version RUN grep "define(_CLIENT_VERSION_MAJOR" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' > /wallet_version -RUN echo -n "." >> /wallet_version +RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_MINOR" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version -RUN echo -n "." >> /wallet_version +RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_REVISION" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_BUILD" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version @@ -69,7 +72,7 @@ RUN sha256sum $(echo $BASE_NAME)-qt >> SHA256SUMS-MacOS-x64.ASC RUN sha256sum $(echo $NAME)-Core.dmg >> SHA256SUMS-MacOS-x64.ASC RUN sha256sum $TICKER-$(cat /wallet_version)-MacOS-x64.zip >> SHA256SUMS-MacOS-x64.ASC -# To compile and build the container execute docker in this way: +# To compile and build the container execute docker in this way: # docker build \ # --build-arg CPU_CORES= \ # --build-arg TICKER= \ diff --git a/contrib/docker/Dockerfile.dsw-windows-x64-wallet b/contrib/docker/Dockerfile.dsw-windows-x64-wallet index d2ef68434..2d9a272e6 100644 --- a/contrib/docker/Dockerfile.dsw-windows-x64-wallet +++ b/contrib/docker/Dockerfile.dsw-windows-x64-wallet @@ -1,5 +1,5 @@ #FROM decenomy/dsw-windows-x64-builder:latest -FROM decenomy/dsw-windows-x64-builder@sha256:849a5356779276649044bc6bdb52fd272a54ec8bb9ce0cf827dd78cf5d32b343 +FROM decenomy/dsw-windows-x64-builder@sha256:6ff1eeff59b4bd279cb056163a573294241616f4c91923b0c494cb3511125333 # ARG for specifying the number of cores ARG CPU_CORES=1 @@ -11,13 +11,16 @@ ARG BASE_NAME=sapphire ARG TARGET=master # Clone the repository -RUN git clone https://github.com/decenomy/$TICKER +RUN if [ ! -d $TICKER ]; then \ + git clone https://github.com/decenomy/$TICKER; \ +fi # Switch to the repository directory WORKDIR /$TICKER # Check out a specific version if needed -RUN git checkout $TARGET +RUN git checkout -B $TARGET +RUN git pull origin $TARGET RUN git log -1 --format="%at" | xargs -I{} date -d @{} "+%Y-%m-%d %H:%M:%S" > /git_timestamp RUN git log -1 --format="%at" | xargs -I{} date -d @{} "+%Y%m%d%H%M.%S" > /git_timestamp_touch @@ -43,9 +46,9 @@ RUN PATH=${WRAP_DIR}:${PATH} make -j$CPU_CORES HOST=x86_64-w64-mingw32 # Extract the wallet version RUN grep "define(_CLIENT_VERSION_MAJOR" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' > /wallet_version -RUN echo -n "." >> /wallet_version +RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_MINOR" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version -RUN echo -n "." >> /wallet_version +RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_REVISION" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version RUN echo -n "." >> /wallet_version RUN grep "define(_CLIENT_VERSION_BUILD" configure.ac | awk -F"[ ,)]" '{print $3}' | tr -d '\n' >> /wallet_version @@ -60,7 +63,7 @@ RUN PATH=${WRAP_DIR}:${PATH} x86_64-w64-mingw32-strip -s \ RUN cp \ src/$(echo $BASE_NAME)d.exe \ src/$(echo $BASE_NAME)-cli.exe \ - src/$(echo $BASE_NAME)-tx.exe \ + src/$(echo $BASE_NAME)-tx.exe \ src/qt/$(echo $BASE_NAME)-qt.exe \ /$TICKER/deploy/windows-x64 RUN find /$TICKER/deploy/windows-x64 -type f -exec touch -t $(cat /git_timestamp_touch) {} + @@ -77,7 +80,7 @@ RUN sha256sum $(echo $BASE_NAME)-cli.exe >> SHA256SUMS-Windows-x64.ASC RUN sha256sum $(echo $BASE_NAME)-tx.exe >> SHA256SUMS-Windows-x64.ASC RUN sha256sum $(echo $BASE_NAME)-qt.exe >> SHA256SUMS-Windows-x64.ASC RUN sha256sum $TICKER-$(cat /wallet_version)-Windows-x64.zip >> SHA256SUMS-Windows-x64.ASC - + # Set the Inno Setup compiler RUN mkdir -p /$TICKER/contrib/innosetup/package RUN cp $(echo $BASE_NAME)* /$TICKER/contrib/innosetup/package/ @@ -97,10 +100,10 @@ RUN PATH=${WRAP_DIR}:${PATH} zip -X $TICKER-$(cat /wallet_version)-WindowsSetup- RUN sha256sum $(echo $NAME)-$(cat /wallet_version)-Setup.exe >> SHA256SUMS-Windows-x64.ASC RUN sha256sum $TICKER-$(cat /wallet_version)-WindowsSetup-x64.zip >> SHA256SUMS-Windows-x64.ASC -# To compile and build the container execute docker in this way: +# To compile and build the container execute docker in this way: # docker build \ # --build-arg CPU_CORES= \ -# --build-arg TICKER= \ +# --build-arg TICKER=> \ # --build-arg NAME= \ # --build-arg BASE_NAME= \ # --build-arg TARGET= \ diff --git a/depends/packages/curl.mk b/depends/packages/curl.mk new file mode 100644 index 000000000..0f113edd4 --- /dev/null +++ b/depends/packages/curl.mk @@ -0,0 +1,23 @@ +package=curl +$(package)_version=8.4.0 +#$(package)_download_path=https://github.com/curl/curl/releases/download/curl-8_4_0/ +$(package)_download_path=https://github.com/decenomy/depends/raw/main/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=816e41809c043ff285e8c0f06a75a1fa250211bbfb2dc0a037eeef39f1a9e427 +$(package)_dependencies=openssl + +define $(package)_set_vars + $(package)_config_opts=--with-openssl --disable-shared --enable-static +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index c63bc7fbe..cbb6bc30c 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -7,8 +7,8 @@ $(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d70 $(package)_build_subdir=cctools $(package)_clang_version=3.7.1 # $(package)_clang_download_path=https://llvm.org/releases/$($(package)_clang_version) -$(package)_clang_download_path=https://github.com/decenomy/depends/raw/main/$($(package)_clang_version) -$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz +$(package)_clang_download_path=https://github.com/decenomy/depends/raw/main/ +$(package)_clang_download_file=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz $(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz $(package)_clang_sha256_hash=99b28a6b48e793705228a390471991386daa33a9717cd9ca007fcdde69608fd9 $(package)_extra_sources=$($(package)_clang_file_name) diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index c8b2ce860..af117f2fa 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -8,7 +8,7 @@ qt_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontcon qt_darwin_packages=qt qt_mingw32_packages=qt -wallet_packages=bdb +wallet_packages=bdb curl zmq_packages=zeromq diff --git a/src/Makefile.am b/src/Makefile.am index b6a3703e5..7e48c17ea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,7 +20,7 @@ LIBUNIVALUE = $(UNIVALUE_LIBS) endif BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config -BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) +BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) $(CURL_CFLAGS) BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include BITCOIN_INCLUDES += $(UNIVALUE_CFLAGS) @@ -87,6 +87,9 @@ BITCOIN_CORE_H = \ bip38.h \ bloom.h \ blocksignature.h \ + bootstrap/bootstrap.h \ + bootstrap/minizip/ioapi.h \ + bootstrap/minizip/unzip.h \ chain.h \ chainparams.h \ chainparamsbase.h \ @@ -272,6 +275,9 @@ libbitcoin_wallet_a_SOURCES = \ activemasternodeconfig.cpp \ activemasternodeman.cpp \ bip38.cpp \ + bootstrap/bootstrap.cpp \ + bootstrap/minizip/ioapi.c \ + bootstrap/minizip/unzip.c \ interface/wallet.cpp \ addressbook.cpp \ crypter.cpp \ @@ -459,7 +465,7 @@ sapphired_LDADD = \ $(LIBMEMENV) \ $(LIBSECP256K1) -sapphired_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) +sapphired_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(CURL_LIBS) $(ZLIB_LIBS) # sapphire-cli binary # sapphire_cli_SOURCES = pivx-cli.cpp diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index bc6ef9a46..0a9e03b02 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -644,7 +644,7 @@ qt_sapphire_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif qt_sapphire_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(SVG_LIBS) $(CHARTS_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ - $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(CURL_LIBS) $(zlib_LIBS) qt_sapphire_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_sapphire_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX diff --git a/src/bootstrap/bootstrap.cpp b/src/bootstrap/bootstrap.cpp new file mode 100644 index 000000000..f0194aa92 --- /dev/null +++ b/src/bootstrap/bootstrap.cpp @@ -0,0 +1,174 @@ + +#include "bootstrap.h" + +namespace fs = boost::filesystem; + + +bool BOOTSTRAP::rmDirectory(const std::string& directory_path) { + + try { + // Check if the directory exists + if (fs::exists(directory_path)) { + // Remove the directory and its contents + fs::remove_all(directory_path); + //std::cout << "Directory removed successfully." << std::endl; + } else { + //std::cerr << "Directory does not exist." << std::endl; + } + } catch (const fs::filesystem_error& ex) { + //std::cerr << "Error removing directory: " << ex.what() << std::endl; + return false; + } + + return true; +} + +bool BOOTSTRAP::isDirectory(const std::string& directory_path) { + + if (fs::exists(directory_path)) return true; + + return false; +} + +// Callback function to write downloaded data to a file +size_t BOOTSTRAP::WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) { + size_t total_size = size * nmemb; + std::ofstream* file = static_cast(userp); + file->write(static_cast(contents), total_size); + return total_size; +} + +// Function to download a file using libcurl +bool BOOTSTRAP::DownloadFile(const std::string& url, const std::string& outputFileName) { + CURL* curl = curl_easy_init(); + if (!curl) { + //std::cerr << "Error initializing libcurl." << std::endl; + return false; + } + + std::ofstream outputFile(outputFileName, std::ios::binary); + if (!outputFile.is_open()) { + //std::cerr << "Error opening output file." << std::endl; + return false; + } + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // Do not verify the peer's SSL certificate + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &outputFile); + + CURLcode res = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + outputFile.close(); + + if (res != CURLE_OK) { + //std::cerr << "Error downloading file: " << curl_easy_strerror(res) << std::endl; + return false; + } + + return true; +} + +bool BOOTSTRAP::extractZip(const std::string& zipFilePath, const std::string& outputFolderPath) { + + // Open the zip file + unzFile zipFile = unzOpen(zipFilePath.c_str()); + if (!zipFile) { + //std::cerr << "Error opening zip file: " << zipFilePath << std::endl; + return false; + } + + // Create the output folder if it doesn't exist + if (!ensureOutputFolder(outputFolderPath)) { + //std::cerr << "Error creating output folder: " << outputFolderPath << std::endl; + unzClose(zipFile); + return false; + } + + // Go through each file in the zip and extract it + unz_global_info globalInfo; + if (unzGetGlobalInfo(zipFile, &globalInfo) != UNZ_OK) { + //std::cerr << "Error getting global info from zip file." << std::endl; + unzClose(zipFile); + return false; + } + + for (uLong i = 0; i < globalInfo.number_entry; ++i) { + char fileName[256]; + unz_file_info fileInfo; + + if (unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, sizeof(fileName), nullptr, 0, nullptr, 0) != UNZ_OK) { + //std::cerr << "Error getting file info from zip file." << std::endl; + unzClose(zipFile); + return false; + } + + if (unzOpenCurrentFile(zipFile) != UNZ_OK) { + //std::cerr << "Error opening current file in zip." << std::endl; + unzClose(zipFile); + return false; + } + + std::string outputPath = std::string(outputFolderPath) + "/" + fileName; + + if(endsWithSlash(outputPath)) + ensureOutputFolder(outputPath); + else{ + std::ofstream outFile(outputPath, std::ios::binary); + if (!outFile.is_open()) { + //std::cerr << "Error creating output file: " << outputPath << std::endl; + unzCloseCurrentFile(zipFile); + unzClose(zipFile); + return false; + } + + // Read and write the file data + char buffer[4096]; + int bytesRead; + + while ((bytesRead = unzReadCurrentFile(zipFile, buffer, sizeof(buffer))) > 0) { + outFile.write(buffer, bytesRead); + } + outFile.close(); + } + + + unzCloseCurrentFile(zipFile); + + if (unzGoToNextFile(zipFile) != UNZ_OK) { + break; // Reached the end of the zip file + } + } + + // Close the zip file + unzClose(zipFile); + //std::cout << "Zip extraction successful." << std::endl; + + return true; + +} + +bool BOOTSTRAP::ensureOutputFolder(const std::string& outputPath) { + try { + if (!fs::exists(outputPath)) { + // Create the directory if it doesn't exist + fs::create_directories(outputPath); + } else if (!fs::is_directory(outputPath)) { + // If it exists but is not a directory, print an error + //std::cerr << "Error: Output path '" << outputPath << "' is not a directory." << std::endl; + return false; + } + } catch (const std::exception& e) { + // Handle any exceptions that may occur during filesystem operations + //std::cerr << "Error creating output folder: " << e.what() << std::endl; + return false; + } + + return true; +} + +bool BOOTSTRAP::endsWithSlash(const std::string& str) { + // Check if the string ends with '/' + return !str.empty() && str.back() == '/'; +} diff --git a/src/bootstrap/bootstrap.h b/src/bootstrap/bootstrap.h new file mode 100644 index 000000000..4d97ec441 --- /dev/null +++ b/src/bootstrap/bootstrap.h @@ -0,0 +1,36 @@ +#ifndef BOOTSTRAP_H +#define BOOTSTRAP_H + +#include // For perror +#include // For strerror +#include +#include +#include +#include + +#include +#include + +#include "minizip/unzip.h" + +#ifndef TICKER +#define TICKER "SAPP" +#endif + +class BOOTSTRAP{ + +public: + + static bool rmDirectory(const std::string& path); + static bool isDirectory(const std::string& path); + static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp); + static bool DownloadFile(const std::string& url, const std::string& outputFileName); + static bool extractZip(const std::string& inputPath, const std::string& outputPath); + +private: + + static bool ensureOutputFolder(const std::string& outputPath); + static bool endsWithSlash(const std::string& str); +}; + +#endif diff --git a/src/bootstrap/minizip/ioapi.c b/src/bootstrap/minizip/ioapi.c new file mode 100644 index 000000000..782d32469 --- /dev/null +++ b/src/bootstrap/minizip/ioapi.c @@ -0,0 +1,231 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS))) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#if defined(__APPLE__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc, const void*filename, int mode) { + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) { + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc, voidpf filestream) { + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (uLong)(*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == MAXU32) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32, const zlib_filefunc_def* p_filefunc32) { + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func(voidpf opaque, const char* filename, int mode) { + FILE* file = NULL; + const char* mode_fopen = NULL; + (void)opaque; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func(voidpf opaque, const void* filename, int mode) { + FILE* file = NULL; + const char* mode_fopen = NULL; + (void)opaque; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = FOPEN_FUNC((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uLong size) { + uLong ret; + (void)opaque; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void* buf, uLong size) { + uLong ret; + (void)opaque; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func(voidpf opaque, voidpf stream) { + long ret; + (void)opaque; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream) { + ZPOS64_T ret; + (void)opaque; + ret = (ZPOS64_T)FTELLO_FUNC((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func(voidpf opaque, voidpf stream, uLong offset, int origin) { + int fseek_origin=0; + long ret; + (void)opaque; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, (long)offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) { + int fseek_origin=0; + long ret; + (void)opaque; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(FSEEKO_FUNC((FILE *)stream, (z_off64_t)offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream) { + int ret; + (void)opaque; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream) { + int ret; + (void)opaque; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc(zlib_filefunc_def* pzlib_filefunc_def) { + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def) { + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/src/bootstrap/minizip/ioapi.h b/src/bootstrap/minizip/ioapi.h new file mode 100644 index 000000000..a2d2e6e60 --- /dev/null +++ b/src/bootstrap/minizip/ioapi.h @@ -0,0 +1,210 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif + +#endif + +#include +#include +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) +#define fopen64 fopen +#define ftello64 ftello +#define fseeko64 fseeko +#endif +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type chosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + + + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + +/* Maximum unsigned 32-bit value used as placeholder for zip64 */ +#ifndef MAXU32 +#define MAXU32 (0xffffffff) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char* filename, int mode); +typedef uLong (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size); +typedef uLong (ZCALLBACK *write_file_func) (voidpf opaque, voidpf stream, const void* buf, uLong size); +typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream); +typedef int (ZCALLBACK *testerror_file_func) (voidpf opaque, voidpf stream); + +typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream); +typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin); + + +/* here is the "old" 32 bits structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) (voidpf opaque, voidpf stream); +typedef long (ZCALLBACK *seek64_file_func) (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin); +typedef voidpf (ZCALLBACK *open64_file_func) (voidpf opaque, const void* filename, int mode); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def); +void fill_fopen_filefunc(zlib_filefunc_def* pzlib_filefunc_def); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64(const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode); +long call_zseek64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin); +ZPOS64_T call_ztell64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/bootstrap/minizip/unzip.c b/src/bootstrap/minizip/unzip.c new file mode 100644 index 000000000..ed763f89f --- /dev/null +++ b/src/bootstrap/minizip/unzip.c @@ -0,0 +1,1985 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from patches received from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression method BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structure of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structure of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const z_crc_t* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ + +local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) { + unsigned char c[2]; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,2); + if (err==2) + { + *pX = c[0] | ((uLong)c[1] << 8); + return UNZ_OK; + } + else + { + *pX = 0; + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + +local int unz64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) { + unsigned char c[4]; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,4); + if (err==4) + { + *pX = c[0] | ((uLong)c[1] << 8) | ((uLong)c[2] << 16) | ((uLong)c[3] << 24); + return UNZ_OK; + } + else + { + *pX = 0; + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +local int unz64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) { + unsigned char c[8]; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,8); + if (err==8) + { + *pX = c[0] | ((ZPOS64_T)c[1] << 8) | ((ZPOS64_T)c[2] << 16) | ((ZPOS64_T)c[3] << 24) + | ((ZPOS64_T)c[4] << 32) | ((ZPOS64_T)c[5] << 40) | ((ZPOS64_T)c[6] << 48) | ((ZPOS64_T)c[7] << 56); + return UNZ_OK; + } + else + { + *pX = 0; + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal(const char* fileName1, const char* fileName2) { + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filenames (fileName1,fileName2). + If iCaseSensitivity = 1, comparison is case sensitive (like strcmp) + If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi + or strcasecmp) + If iCaseSensitivity = 0, case sensitivity is default of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) { + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +#ifndef CENTRALDIRINVALID +#define CENTRALDIRINVALID ((ZPOS64_T)(-1)) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=CENTRALDIRINVALID; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return CENTRALDIRINVALID; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return CENTRALDIRINVALID; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+(unsigned)i; + break; + } + + if (uPosFound!=CENTRALDIRINVALID) + break; + } + free(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) { + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=CENTRALDIRINVALID; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return CENTRALDIRINVALID; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return CENTRALDIRINVALID; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+(unsigned)i; + break; + } + + if (uPosFound!=CENTRALDIRINVALID) + break; + } + free(buf); + if (uPosFound == CENTRALDIRINVALID) + return CENTRALDIRINVALID; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return CENTRALDIRINVALID; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return CENTRALDIRINVALID; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return CENTRALDIRINVALID; + if (uL != 0) + return CENTRALDIRINVALID; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return CENTRALDIRINVALID; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return CENTRALDIRINVALID; + if (uL != 1) + return CENTRALDIRINVALID; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return CENTRALDIRINVALID; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return CENTRALDIRINVALID; + + if (uL != 0x06064b50) + return CENTRALDIRINVALID; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal(const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) { + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spanning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spanning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos!=CENTRALDIRINVALID) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==CENTRALDIRINVALID) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + free(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64* pglobal_info) { + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) { + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easily) +*/ +local void unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate, tm_unz* ptm) { + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (int)(uDate&0x1f) ; + ptm->tm_mon = (int)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (int)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (int) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (int) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (int) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal(unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) { + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + if(file_info.uncompressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == MAXU32) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == 0xffff) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) { + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) { + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if ((err==UNZ_OK) && (pfile_info != NULL)) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date; + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile(unzFile file) { + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile(unzFile file) { + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) { + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) { + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos* file_pos) { + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) { + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos* file_pos) { + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader(unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) { + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method, + int* level, int raw, const char* password) { + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + free(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + free(pfile_in_zip_read_info->read_buffer); + free(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + free(pfile_in_zip_read_info->read_buffer); + free(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile(unzFile file) { + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char* password) { + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int* method, int* level, int raw) { + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file) { + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if some bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->read_buffer == NULL) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : (int)iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + /* Detect overflow, because z_stream.total_out is uLong (32 bits) */ + if (uTotalOutAftertotal_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : (int)iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return (int)iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell(unzFile file) { + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64(unzFile file) { + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof(unzFile file) { + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) { + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile(unzFile file) { + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + free(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + free(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment(unzFile file, char * szComment, uLong uSizeBuf) { + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) { + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset(unzFile file) { + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) { + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) { + return unzSetOffset64(file,pos); +} diff --git a/src/bootstrap/minizip/unzip.h b/src/bootstrap/minizip/unzip.h new file mode 100644 index 000000000..14105840f --- /dev/null +++ b/src/bootstrap/minizip/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + int tm_sec; /* seconds after the minute - [0,59] */ + int tm_min; /* minutes after the hour - [0,59] */ + int tm_hour; /* hours since midnight - [0,23] */ + int tm_mday; /* day of the month - [1,31] */ + int tm_mon; /* months since January - [0,11] */ + int tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare(const char* fileName1, + const char* fileName2, + int iCaseSensitivity); +/* + Compare two filenames (fileName1,fileName2). + If iCaseSensitivity = 1, comparison is case sensitive (like strcmp) + If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi + or strcasecmp) + If iCaseSensitivity = 0, case sensitivity is default of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen(const char *path); +extern unzFile ZEXPORT unzOpen64(const void *path); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2(const char *path, + zlib_filefunc_def* pzlib_filefunc_def); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64(const void *path, + zlib_filefunc64_def* pzlib_filefunc_def); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose(unzFile file); +/* + Close a ZipFile opened with unzOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzCloseCurrentFile before call unzClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo(unzFile file, + unz_global_info *pglobal_info); + +extern int ZEXPORT unzGetGlobalInfo64(unzFile file, + unz_global_info64 *pglobal_info); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment(unzFile file, + char *szComment, + uLong uSizeBuf); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile(unzFile file); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile(unzFile file); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile(unzFile file, + const char *szFileName, + int iCaseSensitivity); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize); + +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain some info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile(unzFile file); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, + const char* password); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2(unzFile file, + int* method, + int* level, + int raw); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3(unzFile file, + int* method, + int* level, + int raw, + const char* password); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile(unzFile file); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile(unzFile file, + voidp buf, + unsigned len); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if some bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell(unzFile file); + +extern ZPOS64_T ZEXPORT unztell64(unzFile file); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof(unzFile file); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, + voidp buf, + unsigned len); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */ diff --git a/src/chainparams.cpp b/src/chainparams.cpp index a8aa68203..ad95fcbe0 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -70,111 +70,13 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits static Checkpoints::MapCheckpoints mapCheckpoints = boost::assign::map_list_of (0, uint256S("00000eef0583695d6da23a78bab1c39939bbb54cf9bd5f0d4881c8eef364cd26")) - (22466, uint256S("24f3f4e17b7542cf87a0264f5c574cd908209159ed8c798d290afd4491fe7a8a")) - (44933, uint256S("3689dac544301ff0be3fd01eb39717fc4fc21c50d23ff1397845555c82bbc1fa")) - (67400, uint256S("7858c3dbc12136c9b924d698dc210165b6e3c9b656c4d9cfbf3259f3bc0ae826")) - (89867, uint256S("81bd7b22f2be94b263ef6377f5a04c505bdf6b30e53e9d19f42a27853e6e37bb")) - (112334, uint256S("6881a446123f5fc47ae0751ec924259de8d0829e9d87488066ae08689bc3d64f")) - (134801, uint256S("54b239d2e5e9c91f646d0e9fe49ab426cdfd9691e2dddf333238442dc5dc1108")) - (157268, uint256S("921eda5b1a20ec5b799b2d3f2fd5709118541338578c5b8b863d064aa92f6300")) - (179735, uint256S("2fb007c3143b38166dc777594f624f88f3ff999c754610379fae00c6c9eab652")) - (202202, uint256S("af8539b761c2e2a27e8dddecf9f92bd9c3cc29786754dfd468b3584d21b97dc7")) - (224669, uint256S("5f5dc667dd0b931716bfb5d9e25aa4dcb84094c09984942a51740aca3a6857db")) - (247136, uint256S("6291c32267475ef1eeaa37dd158816f6bff17c0bf904e5138e733f4806832959")) - (269603, uint256S("445f1ed229644ae5333532b5ff97623010afc5c14c8b7bf81c37f614fd68f52e")) - (292070, uint256S("f0194e93ccf7cc31172841f427f11417cf1d5ce1d30ba0493a015bc1380fa90e")) - (314537, uint256S("831461f7bbe31acd71bf14bf201ec43e260580f22d93ffba30fb562056166ff6")) - (337004, uint256S("430f328c6eed9a26d015ab60b19a561511347a670738dd54577defb350e772b8")) - (359471, uint256S("bf357546edbb332c51182f92542c89f465df6b490d728a3070c4ff5a6f9461bb")) - (381938, uint256S("f8301646f34d657d2137a1fedef46cc09919ce3cfb114c84b29187a9097a29b5")) - (404405, uint256S("4331dad426c7cd9e532c2d351ce598da79e20e47bd197eb3774e67f810c148f9")) - (426872, uint256S("0f46f2c4a86f8639b7f7c6101a659cc955b70c79f2558bf8e37f75c6bbeec564")) - (449339, uint256S("3e132f3be2a2918728bbb63d85e469b59da90feadc3acc1774d0b3ae6194917e")) - (471806, uint256S("30b1af2c222602e8c17edda3202ef3fe3a896cde1fc96ae742817196ca18e5bb")) - (494273, uint256S("51e87e69df8052e710fa0eb9af82ef30d039ba870f3af4bd15e7601e7483af04")) - (516740, uint256S("646763c50f67ec1535e5159a5ce54d5cf6b6fdeee5772c33cb5186914280a30b")) - (539207, uint256S("7b68497023b59d516b335ab075d115e0066a186c4c2bfe8c0ddd93ceb570d09f")) - (561674, uint256S("062e12a95e5645a63b93a3b2e08a447e1fbd0501e03d7d7836bc772b7bb4c9c5")) - (584141, uint256S("8d25a902fe87753d23eb96e32486e614ae3f6e2eb8d8290a3d989ee8a48db693")) - (606608, uint256S("d5a776a2e3f6d0595d92fd03df5285cdabf15d8fc289f4e8e5d97ffea689fa3b")) - (629075, uint256S("134c84cf852203fea430d95128c950dc11ea01c2cbdbab0694c5c99aa46be5c3")) - (651542, uint256S("cdd642719a9f64cbdf1ddea39ec74760388690a13d8097a3252ebc7d2fa22535")) - (674009, uint256S("0740790eea5582face68c990915beec97d65720886a4f85d0b12ca8e5f5c72b6")) - (696476, uint256S("6f61dc376050d22dd0d0b8587a572fa8e7eb082a2270397739fbc826daec8d21")) - (718943, uint256S("3c94bfacb49b9e0e3188288bc439fc35f6283c77866835c0dfe7dee948bb901f")) - (741410, uint256S("5c62daf1905bda978b86bef2d6385066e8f8ed419618de3b86ea53e28d336904")) - (763877, uint256S("d8e4e2d06b7f3e95ba798b5b599e7b84bcdb2fd01119a39223322bbb0f0869ec")) - (786344, uint256S("b29fe14838ff46678f1f360a159040ffc514ce19dfbcd5a345c3a8c16ea9b8f4")) - (808811, uint256S("dcee4e6f8b34b82f24ee2bd47772a7633209347c5ed2ccadda3afeb2055379a5")) - (831278, uint256S("860ef14998bf701920cfb6c20c1816a257022bf83c28b0ddd93fe8abe58a508d")) - (853745, uint256S("add6c0dcf01d9c011c2c9f2dcabae0774e26957864b5c5bb077cbb40c53d8f92")) - (876212, uint256S("be3fbf3e00663fd003d5f3f4264cc7bc6a2761dfbf341ba8ba0e58642c36ea30")) - (898679, uint256S("3bb800281c0f1317d7e647460b774e45e3b8eda8e5e2e1888fc7d1d2101a3093")) - (921146, uint256S("ce454252560f4e058b05bcbfcc4270961df2bde996e0d8e7c83603e1199600c0")) - (943613, uint256S("2d9b03b60016ad8baf6720d870203032d676c5363e93b483b393a6fcd085e0d6")) - (966080, uint256S("1743d0f8f64c85c2513a796d872577eb06f85a668413a5ddf62b00998f3e09f2")) - (988547, uint256S("2f7ec62bd104290310246375cbb5af27bfdb0ec76ae453560e4c13f8556eb253")) - (1011014, uint256S("39f1372066cba47cfe8fcad97446c7a674b38acba70158f9ef8330a8acd13b7b")) - (1033481, uint256S("7c7fb2ff34a3a3246632ea647c6edc11bca737594d170939ba75091259bc04e5")) - (1055948, uint256S("c8b1b4f3465c9a4ac213496ecb9d4884c38aa68d2dd5e0ae091b5dcf31375043")) - (1078415, uint256S("866f4685533ba2dede4d5069e8bc7e67a5b390b57993f31dd71db531e3a2fa43")) - (1100882, uint256S("2f173ab007d8b0552c4bd35862b771de654429bb369b4675abc264fdaa5978a3")) - (1123349, uint256S("92dc3e59bbf42a6eff7d89c29e9f799bbd56861da31718880c0a59f63ab0b3ad")) - (1145816, uint256S("33980e61d91c1bd871034ec196e21a869b76fc1121ed2f1c8af2fcb8117f0a63")) - (1168283, uint256S("05193b8845c03286de00a5053d43acb67722790049514761826260e8e0454f85")) - (1190750, uint256S("46b48017d79db5c368ece44717a7ac20266f590868bbe255f76ff4ba12d0de31")) - (1213217, uint256S("f64cad8107c3be7c5b080b73320c8d8652a75c25c27ddfae7978f14cd00a37c0")) - (1235684, uint256S("d03aae7d47b51d38afc2acfd04739814cabf260719178faf87487594f9beb9cd")) - (1258151, uint256S("5e8a3d0ac7629f6500c6d499d3a7e4142da2f18e0befd62dc7a58473f6357a3b")) - (1280618, uint256S("ff669d2e4f079b50697f9d9882d87d3ad3c91bb46f56bc4f0372afd262545335")) - (1303085, uint256S("3c168c9429d1aa35152e80f1f757cc954d808cac38ae0331d04433018f24c36a")) - (1325552, uint256S("a947ab57049102decd9d6e92dcf62920ef15016e5c3976e6cc882bf3ab28e956")) - (1348019, uint256S("6a52fcb555fafbd77066ef927edaece4e0ad0325aaafe7fb534fc700d6de777c")) - (1370486, uint256S("f257ec8fc7c92772ad567aa6e91d2b3d767b2615656ffb2adb8092be0aa8cb2a")) - (1392953, uint256S("8893e4afade8d6f4b67d8c132884ecc598df077e6deca14316f5191df0d88e59")) - (1415420, uint256S("1f7c287b171dbf52e15ec7c928a7029480cfdb3dadf87a9363c5fab1d3bd2928")) - (1437887, uint256S("28912d9a6b2298a52c3a679fed63d58e31e94277a2f3edfdbdc24a702347d29a")) - (1460354, uint256S("1bc8072116490c2af3da0993558ae594f053b18870742c6c4c1fd05a530e2a3a")) - (1482821, uint256S("edb1fbabdf7980422fb480fdab13bb0892378a85e0ddb549038f2acba477517e")) - (1505288, uint256S("a724fc247fd488d4505d0e1cc8ea6adcc511d6227eb7497fecfe7775561075f3")) - (1527755, uint256S("30fdd321e38a5c0582468cd9e088c5810b88257f268a19d33b0f111de511546a")) - (1550222, uint256S("6d6440c079ffde58a1e89276a618c42506958be85f8a7df231ff7c20bc2686d9")) - (1572689, uint256S("87befcefa6099dc132a855af89436920d00b8ed0b8b7fb97c677e8058f773435")) - (1595156, uint256S("fa1c2a9ce671ae34b36879696120591400cd0bf5407b5d0989d4935cd0c8823f")) - (1617623, uint256S("bb3f08a7767200a9006491bfeb5414927249e1267e271236d8cece5a06dd63e2")) - (1640090, uint256S("21855331f1da1a86ccd2352c79a6ce046cf8c68ad1057e70a371a2d7401a8919")) - (1662557, uint256S("89654e5e4be787380457f099fc57a370baa9053aeb4dab10ad21dfbf089c2137")) - (1685024, uint256S("c4b8ab2b1ae9e905f3c9e7449c6e6226d217a30771242ee5e30251a0f38b4db1")) - (1707491, uint256S("008a4e40fefcdba035e8ebf9cf3e165d9d8906fa0921a83ef84852629b308f99")) - (1729958, uint256S("fc82cf1ae9370521887fefe230dd684e83b595f7cdf538ad609d71742dc361bf")) - (1752425, uint256S("5173fedfc9be7fbbc0ad81d760d59d8e1e5a728c18913d66118adb75c26b5470")) - (1774892, uint256S("b5073b2d3875340c9884dfe1b3921fe714e2d17443dd4d541d46b5d06bb99128")) - (1797359, uint256S("182b27b0197459b509bcd35c71747e5b3ca53c2b48cb19614ec697fecbd3e683")) - (1819826, uint256S("04e01397d342911c8bd777e6bd95d3793111c44210b4be30d8e75d8832a3782c")) - (1842293, uint256S("854c6b3ecae5b86fa3c212f65d4c1a9cc09d1873f7663fd9b5f1f9034a9f115e")) - (1864760, uint256S("0a3b42c00c87b46d8e9b9185dd94ed98f32d7b5880eb2d8ae92707cd653a82e5")) - (1887227, uint256S("7e58d8c1c0d92429695410043274a343561c02d2c319dc3aa683153d762a24a7")) - (1909694, uint256S("da4eb4d7aa74791566290a84b38a3af748adec4083db6138fe0a455ff36995c2")) - (1932161, uint256S("9abcba5ac1d0b5145c59bb63ba991ae2a2e807e27b64ec71c21c04fcddfd322c")) - (1954628, uint256S("6ff4f4c60d417a6a14c4caff7a0ec86b03751c02d66a1ecc30cd0b45e9e1ceea")) - (1977095, uint256S("cab307e233594cd0913edd2f8b3bf763b26044e2832b9610619c73049f7cd669")) - (1999562, uint256S("02711ddf5ab3c41cc53c9f1c1928ced4ace06c93760185487064e50db85366f1")) - (2022029, uint256S("2cb7f22ff1cef414b2b42b421b2619d4c48ffb0642b1c1b927289b40df552033")) - (2044496, uint256S("97255c33e7b5fcdc5825085be9db5070fa568dcc500eeb68f3e41a5bbb755ae0")) - (2066963, uint256S("32d17ce0a360bebff6fe47bbaff912135e0ad571e06eaec3b9ec418d48dabc02")) - (2089430, uint256S("72f3111be54ff868fcfcd50c1d8f03af6df463d265298d5dd3bcfb1262748a9e")) - (2111897, uint256S("1fce1cd5a690866387d15ea80ed9810b2808447ae0a07bfa4a150e7d76f23c67")) - (2134364, uint256S("0df8b5a35696adb55ace7c3091642e2cf26691db9fb721969ab3c646894c689f")) - (2156831, uint256S("c049f8acea91c2fa481f9bef41ab52ab26dec064ea179c359b3b6e8ff7bdf630")) - (2179298, uint256S("0091149a35034db47074bf725868246740f0502481e3445ddc6ceb5269a078ef")) - (2201765, uint256S("c0a5e1b81c67b2ed73b0e1b5d036b52be9a861c71e7ddcb06fd49df60831fef7")) - (2224232, uint256S("064e3c900836537257cf1f218b76f9cdf1f25209259ab501f07d5b9edf51ab47")) + ; static const Checkpoints::CCheckpointData data = { &mapCheckpoints, - 1691600340, // * UNIX timestamp of last checkpoint block - 14240675, // * total number of transactions between genesis and last checkpoint + 0, // * UNIX timestamp of last checkpoint block + 1, // * total number of transactions between genesis and last checkpoint // (the tx=... number in the UpdateTip debug.log lines) 2826 // * estimated number of transactions per day after checkpoint }; diff --git a/src/init.cpp b/src/init.cpp index 321400291..b09b85376 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -403,7 +403,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); #endif strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), DEFAULT_TXINDEX)); - + strUsage += HelpMessageGroup(_("Connection options:")); strUsage += HelpMessageOpt("-addnode=", _("Add a node to connect to and attempt to keep the connection open")); strUsage += HelpMessageOpt("-banscore=", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), DEFAULT_BANSCORE_THRESHOLD)); @@ -1203,8 +1203,13 @@ bool AppInit2() } } - if (GetBoolArg("-resync", false)) { - uiInterface.InitMessage(_("Preparing for resync...")); + if (GetBoolArg("-resync", false) || GetBoolArg("-bootstrap", false) ) { + + if (GetBoolArg("-resync", false)) + uiInterface.InitMessage(_("Preparing for resync...")); + else if (GetBoolArg("-bootstrap", false)) + uiInterface.InitMessage(_("Preparing for bootstrap...")); + // Delete the local blockchain folders to force a resync from scratch to get a consitent blockchain-state fs::path blocksDir = GetDataDir() / "blocks"; fs::path chainstateDir = GetDataDir() / "chainstate"; @@ -1227,6 +1232,42 @@ bool AppInit2() fs::remove_all(sporksDir); LogPrintf("-resync: folder deleted: %s\n", sporksDir.string().c_str()); } + #ifdef ENABLE_BOOTSTRAP + if (GetBoolArg("-bootstrap", false)) { + const std::string url = std::string(BOOTSTRAP_URL)+std::string(TICKER)+"/bootstrap.zip"; + const std::string outputFileName = "bootstrap.zip"; + const std::string extractPath = "bootstrap_"; + + LogPrintf("-bootstrap: Download: %s\n", url.c_str()); + + if(BOOTSTRAP::isDirectory(extractPath)) + BOOTSTRAP::rmDirectory(extractPath); + + if (BOOTSTRAP::DownloadFile(url, outputFileName)) { + LogPrintf("-bootstrap: File downloaded successfully \n"); + + if (BOOTSTRAP::extractZip(outputFileName, extractPath)) { + LogPrintf("-bootstrap: Zip file extracted successfully \n"); + try { + fs::rename(extractPath+"/blocks", blocksDir); + fs::rename(extractPath+"/chainstate", chainstateDir); + LogPrintf("-bootstrap: Folders moved successfully \n"); + fs::remove(extractPath); + } catch (const std::exception& e) { + LogPrintf("-bootstrap: Error moving folder: %s\n",e.what()); + } + } else { + LogPrintf("-bootstrap: Error extracting zip file"); + } + + fs::remove(outputFileName); + } else { + LogPrintf("-bootstrap: Error downloading file"); + } + } + #else + LogPrintf("-bootstrap: not enabled\n"); + #endif } catch (const fs::filesystem_error& error) { LogPrintf("Failed to delete blockchain folders %s\n", error.what()); } diff --git a/src/init.h b/src/init.h index e86daf0ec..14e7268ef 100644 --- a/src/init.h +++ b/src/init.h @@ -10,6 +10,8 @@ #include +#include "bootstrap/bootstrap.h" + const bool DEFAULT_PROXYRANDOMIZE = true; const bool DEFAULT_REST_ENABLE = false; const bool DEFAULT_DISABLE_SAFEMODE = false; diff --git a/src/main.cpp b/src/main.cpp index 33518c321..0239e3439 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1087,6 +1087,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, bool fIgnoreFees) { + LOCK(cs_main); std::vector coins_to_uncache; bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, fOverrideMempoolLimit, fRejectAbsurdFee, fIgnoreFees, coins_to_uncache); if (!res) { @@ -3379,7 +3380,7 @@ bool AcceptBlockHeader(const CBlock& block, CValidationState& state, CBlockIndex pindex = miSelf->second; if (ppindex) *ppindex = pindex; - if (pindex->nStatus & BLOCK_FAILED_MASK) + if (pindex->nStatus & BLOCK_FAILED_MASK && mapRejectedBlocks.find(hash) == mapRejectedBlocks.end()) return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate"); return true; } diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index d71a74a17..787091017 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -21,9 +21,6 @@ /** Object for who's going to get paid on which blocks */ CMasternodePayments masternodePayments; -uint64_t reconsiderWindowMin = 0; -uint64_t reconsiderWindowTime = 0; - RecursiveMutex cs_vecPayments; RecursiveMutex cs_mapMasternodeBlocks; RecursiveMutex cs_mapMasternodePayeeVotes; @@ -253,44 +250,22 @@ bool IsBlockPayeeValid(const CBlock& block, int nBlockHeight) const bool isPoSActive = Params().GetConsensus().NetworkUpgradeActive(nBlockHeight, Consensus::UPGRADE_POS); const CTransaction& txNew = (isPoSActive ? block.vtx[1] : block.vtx[0]); - auto t = GetTime(); - - if((t - reconsiderWindowTime) > HOUR_IN_SECONDS) { // shift the reconsider window at each hour - reconsiderWindowMin = GetRand() % 10; // choose randomly from minute 0 to minute 9 - reconsiderWindowTime = t; - - for (auto it = mapRejectedBlocks.cbegin(); it != mapRejectedBlocks.cend();) { // clean up old entries - it = (GetAdjustedTime() - (*it).second) > DAY_IN_SECONDS ? mapRejectedBlocks.erase(it) : std::next(it); - } - } - //check for masternode payee if (masternodePayments.IsTransactionValid(txNew, nBlockHeight)) return true; + LogPrint(BCLog::MASTERNODE,"Invalid mn payment detected %s\n", txNew.ToString().c_str()); // fails if spork 8 is enabled and // spork 113 is disabled or current time is outside the reconsider window if (sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) { - if (!sporkManager.IsSporkActive(SPORK_113_RECONSIDER_WINDOW_ENFORCEMENT)) - { - return false; - } - - if ((t / MINUTE_IN_SECONDS) % 10 != reconsiderWindowMin) - { - return false; - } - - LogPrint(BCLog::MASTERNODE,"Masternode payment enforcement reconsidered, accepting block\n"); + return false; + } else { + LogPrint(BCLog::MASTERNODE,"Masternode payment enforcement is disabled, accepting block\n"); return true; } - - LogPrint(BCLog::MASTERNODE,"Masternode payment enforcement is disabled, accepting block\n"); - return true; } - void FillBlockPayee(CMutableTransaction& txNew, const CBlockIndex* pindexPrev, bool fProofOfStake) { masternodePayments.FillBlockPayee(txNew, pindexPrev, fProofOfStake); diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index e8cbcc73d..373354b39 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -1579,7 +1579,37 @@ - + + + + + 100 + 23 + + + + Bootstrap Blockchain + + + + + + + -bootstrap: + + + + + + + Deletes all local blockchain folders and loads blockchain from source. + + + true + + + + Qt::Vertical diff --git a/src/qt/pivx/qtutils.h b/src/qt/pivx/qtutils.h index afd266dd6..98b0e1afa 100644 --- a/src/qt/pivx/qtutils.h +++ b/src/qt/pivx/qtutils.h @@ -31,6 +31,7 @@ const QString UPGRADEWALLET("-upgradewallet"); const QString REINDEX("-reindex"); const QString RESYNC("-resync"); const QString REWIND("-rewindblockindex="); +const QString BOOTSTRAP("-bootstrap"); extern Qt::Modifier SHORT_KEY; diff --git a/src/qt/pivx/settings/forms/settingswalletrepairwidget.ui b/src/qt/pivx/settings/forms/settingswalletrepairwidget.ui index 459a85728..8e67f36a8 100644 --- a/src/qt/pivx/settings/forms/settingswalletrepairwidget.ui +++ b/src/qt/pivx/settings/forms/settingswalletrepairwidget.ui @@ -734,6 +734,71 @@ + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 20 + + + + + 0 + + + + + + 0 + 40 + + + + + 16777215 + 40 + + + + Qt::NoFocus + + + Bootstrap blockchain + + + + + + + + + Deletes all local blockchain folders and loads entire blockchain from source + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + Qt::Vertical diff --git a/src/qt/pivx/settings/settingswalletrepairwidget.cpp b/src/qt/pivx/settings/settingswalletrepairwidget.cpp index 77cac799c..9bce1f699 100644 --- a/src/qt/pivx/settings/settingswalletrepairwidget.cpp +++ b/src/qt/pivx/settings/settingswalletrepairwidget.cpp @@ -27,12 +27,14 @@ SettingsWalletRepairWidget::SettingsWalletRepairWidget(PIVXGUI* _window, QWidget // Labels setCssProperty({ui->labelMessageSalvage, ui->labelMessageRescan, ui->labelMessageRecover1, ui->labelMessageRecover2, ui->labelMessageUpgrade, ui->labelMessageRebuild, - ui->labelMessageDelete, ui->labelMessageRewind, ui->labelMessageWeekRewind}, "text-main-settings"); + ui->labelMessageDelete, ui->labelMessageRewind, ui->labelMessageWeekRewind, + ui->labelMessageBootstrap}, "text-main-settings"); // Buttons setCssProperty({ui->pushButtonSalvage, ui->pushButtonRescan, ui->pushButtonRecover1, ui->pushButtonRecover2, ui->pushButtonUpgrade, ui->pushButtonRebuild, - ui->pushButtonDelete, ui->pushButtonRewind, ui->pushButtonWeekRewind}, "btn-primary"); + ui->pushButtonDelete, ui->pushButtonRewind, ui->pushButtonWeekRewind, + ui->pushButtonBootstrap}, "btn-primary"); // Wallet Repair Buttons connect(ui->pushButtonSalvage, &QPushButton::clicked, this, &SettingsWalletRepairWidget::walletSalvage); @@ -44,6 +46,7 @@ SettingsWalletRepairWidget::SettingsWalletRepairWidget(PIVXGUI* _window, QWidget connect(ui->pushButtonDelete, &QPushButton::clicked, this, &SettingsWalletRepairWidget::walletResync); connect(ui->pushButtonRewind, &QPushButton::clicked, this, &SettingsWalletRepairWidget::walletRewind); connect(ui->pushButtonWeekRewind, &QPushButton::clicked, this, &SettingsWalletRepairWidget::walletWeekRewind); + connect(ui->pushButtonBootstrap, &QPushButton::clicked, this, &SettingsWalletRepairWidget::walletBootstrap); } /** Restart wallet with "-salvagewallet" */ @@ -148,6 +151,27 @@ void SettingsWalletRepairWidget::walletWeekRewind() buildParameterlist(tr((REWIND.toStdString() + param).c_str())); } +/** Restart wallet with "-resync" */ +void SettingsWalletRepairWidget::walletBootstrap() +{ + QString bootstrapWarning = tr("This will delete your local blockchain folders and the wallet will load all blockchain from source.

"); + bootstrapWarning += tr("This needs a few minutes to load all data.

"); + bootstrapWarning += tr("Your transactions and funds will be visible again after the download has completed.

"); + bootstrapWarning += tr("Do you want to continue?.
"); + QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm bootstrap Blockchain"), + bootstrapWarning, + QMessageBox::Yes | QMessageBox::Cancel, + QMessageBox::Cancel); + + if (retval != QMessageBox::Yes) { + // Resync canceled + return; + } + + // Restart and resync + buildParameterlist(BOOTSTRAP); +} + /** Build command-line parameter list for restart */ void SettingsWalletRepairWidget::buildParameterlist(QString arg) { diff --git a/src/qt/pivx/settings/settingswalletrepairwidget.h b/src/qt/pivx/settings/settingswalletrepairwidget.h index 56328ae20..245f81136 100644 --- a/src/qt/pivx/settings/settingswalletrepairwidget.h +++ b/src/qt/pivx/settings/settingswalletrepairwidget.h @@ -38,6 +38,7 @@ public Q_SLOTS: void walletResync(); void walletRewind(); void walletWeekRewind(); + void walletBootstrap(); private: Ui::SettingsWalletRepairWidget *ui; diff --git a/src/qt/pivxstrings.cpp b/src/qt/pivxstrings.cpp index d71585f61..7bfc24999 100644 --- a/src/qt/pivxstrings.cpp +++ b/src/qt/pivxstrings.cpp @@ -359,6 +359,7 @@ QT_TRANSLATE_NOOP("pivx-core", "Options:"), QT_TRANSLATE_NOOP("pivx-core", "Password for JSON-RPC connections"), QT_TRANSLATE_NOOP("pivx-core", "Peers are being disconnected due time differences."), QT_TRANSLATE_NOOP("pivx-core", "Preparing for resync..."), +QT_TRANSLATE_NOOP("pivx-core", "Preparing for bootstrap..."), QT_TRANSLATE_NOOP("pivx-core", "Prepend debug output with timestamp (default: %u)"), QT_TRANSLATE_NOOP("pivx-core", "Print version and exit"), QT_TRANSLATE_NOOP("pivx-core", "Pubcoin not found in mint tx"), diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index ee584e0dc..8f4153129 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -55,6 +55,7 @@ const QString UPGRADEWALLET("-upgradewallet"); const QString REINDEX("-reindex"); const QString RESYNC("-resync"); const QString REWIND("-rewindblockindex"); +const QString BOOTSTRAP("-bootstrap"); const struct { const char* url; @@ -283,6 +284,7 @@ RPCConsole::RPCConsole(QWidget* parent) : QDialog(parent, Qt::WindowSystemMenuHi connect(ui->btn_upgradewallet, &QPushButton::clicked, this, &RPCConsole::walletUpgrade); connect(ui->btn_reindex, &QPushButton::clicked, this, &RPCConsole::walletReindex); connect(ui->btn_resync, &QPushButton::clicked, this, &RPCConsole::walletResync); + connect(ui->btn_bootstrap, &QPushButton::clicked, this, &RPCConsole::walletBootstrap); // set library version labels #ifdef ENABLE_WALLET @@ -567,6 +569,27 @@ void RPCConsole::walletResync() buildParameterlist(RESYNC); } +/** Restart wallet with "-bootstrap" */ +void RPCConsole::walletBootstrap() +{ + QString bootstrapWarning = tr("This will delete your local blockchain folders and the wallet will load blockchain from source.

"); + bootstrapWarning += tr("This needs a few minutes to download all data.

"); + bootstrapWarning += tr("Your transactions and funds will be visible again after the download has completed.

"); + bootstrapWarning += tr("Do you want to continue?.
"); + QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm bootstrap Blockchain"), + bootstrapWarning, + QMessageBox::Yes | QMessageBox::Cancel, + QMessageBox::Cancel); + + if (retval != QMessageBox::Yes) { + // Resync canceled + return; + } + + // Restart and bootstrap + buildParameterlist(BOOTSTRAP); +} + /** Build command-line parameter list for restart */ void RPCConsole::buildParameterlist(QString arg) { @@ -583,6 +606,7 @@ void RPCConsole::buildParameterlist(QString arg) args.removeAll(REINDEX); args.removeAll(RESYNC); args.removeAll(REWIND); + args.removeAll(BOOTSTRAP); // Append repair parameter to command line. args.append(arg); @@ -1055,4 +1079,3 @@ void RPCConsole::showOrHideBanTableIfRequired() ui->banlistWidget->setVisible(visible); ui->banHeading->setVisible(visible); } - diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 663168b27..8027ac12f 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -82,6 +82,7 @@ public Q_SLOTS: void walletUpgrade(); void walletReindex(); void walletResync(); + void walletBootstrap(); void reject(); void message(int category, const QString &msg) { message(category, msg, false); } diff --git a/src/spork.cpp b/src/spork.cpp index dd438a490..011991c6d 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -30,7 +30,6 @@ std::vector sporkDefs = { MAKE_SPORK_DEF(SPORK_110_FORCE_ENABLED_MASTERNODE_PAYMENT, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_111_ALLOW_DUPLICATE_MN_IPS, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_112_MASTERNODE_LAST_PAID_V2, 4070908800ULL), // OFF - MAKE_SPORK_DEF(SPORK_113_RECONSIDER_WINDOW_ENFORCEMENT, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_114_MN_PAYMENT_V2, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_115_MN_COLLATERAL_WINDOW, 4070908800ULL), // OFF @@ -52,6 +51,7 @@ std::vector sporkDefs = { MAKE_SPORK_DEF(SPORK_21_NOOP, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_22_NOOP, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_24_NOOP, 4070908800ULL), // OFF + MAKE_SPORK_DEF(SPORK_113_NOOP, 4070908800ULL), // OFF }; CSporkManager sporkManager; diff --git a/src/sporkid.h b/src/sporkid.h index c302703a9..4a94d5a48 100644 --- a/src/sporkid.h +++ b/src/sporkid.h @@ -28,7 +28,6 @@ enum SporkId : int32_t { SPORK_110_FORCE_ENABLED_MASTERNODE_PAYMENT = 10109, SPORK_111_ALLOW_DUPLICATE_MN_IPS = 10110, SPORK_112_MASTERNODE_LAST_PAID_V2 = 10111, - SPORK_113_RECONSIDER_WINDOW_ENFORCEMENT = 10112, SPORK_114_MN_PAYMENT_V2 = 10113, SPORK_115_MN_COLLATERAL_WINDOW = 10114, @@ -50,6 +49,7 @@ enum SporkId : int32_t { SPORK_21_NOOP = 10020, SPORK_22_NOOP = 10021, SPORK_24_NOOP = 10023, + SPORK_113_NOOP = 10112, SPORK_INVALID = -1 };