mirror of
https://codeberg.org/nahuhh/wownero
synced 2026-03-05 06:07:35 -05:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a58ac48d2 | ||
|
|
90b7699717 | ||
|
|
1917bd3d53 | ||
|
|
cb654bbc27 | ||
|
|
ec60b05faa | ||
|
|
58e1f2f02a | ||
|
|
af941bed58 | ||
|
|
10c30ea5aa | ||
|
|
83fe535888 | ||
|
|
e52e01a445 | ||
|
|
284ec84502 | ||
|
|
86f12066f2 | ||
|
|
c336e15f0c | ||
|
|
e09d17ba1f | ||
|
|
9364b49ecb | ||
|
|
5cd3a15491 | ||
|
|
b303931b23 | ||
|
|
7b4e1b0859 | ||
|
|
8fb16a3280 | ||
|
|
4e097c26a2 | ||
|
|
2aabc5863e | ||
|
|
2a6d817ea1 | ||
|
|
f6533856df | ||
|
|
32497a641c | ||
|
|
aaa015b3e7 | ||
|
|
9c35901592 | ||
|
|
f9c0871877 | ||
|
|
96d1d08f48 | ||
|
|
2e8fae1b4c | ||
|
|
d99c27e24d | ||
|
|
48eeca2077 | ||
|
|
96ae690083 | ||
|
|
b9974f7bff | ||
|
|
389a02d93f | ||
|
|
a3c9befbb5 | ||
|
|
08a0e737f9 | ||
|
|
1396426d59 | ||
|
|
93cc82423e | ||
|
|
572d7ea5ef |
10
.drone.yml
Normal file
10
.drone.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: linux-build
|
||||
|
||||
steps:
|
||||
- name: linux-build
|
||||
image: wownero/wow-dependencies:v1.0
|
||||
commands:
|
||||
- make -j2 release-static-linux-x86_64
|
||||
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
custom: https://dev-funding.webui.wowkira.com
|
||||
137
.github/workflows/build.yml
vendored
137
.github/workflows/build.yml
vendored
@@ -1,44 +1,21 @@
|
||||
name: ci/gh-actions/cli
|
||||
name: continuous-integration/gh-actions/cli
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
# The below variables reduce repetitions across similar targets
|
||||
env:
|
||||
REMOVE_BUNDLED_BOOST : rm -rf /usr/local/share/boost
|
||||
APT_INSTALL_LINUX: 'sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache'
|
||||
APT_SET_CONF: |
|
||||
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
|
||||
jobs:
|
||||
build-macos:
|
||||
runs-on: macOS-latest
|
||||
env:
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: /Users/runner/Library/Caches/ccache
|
||||
key: ccache-macos-build-${{ github.sha }}
|
||||
restore-keys: ccache-macos-build-
|
||||
- name: install dependencies
|
||||
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi zmq libpgm miniupnpc ldns expat libunwind-headers protobuf ccache
|
||||
- name: update brew and install dependencies
|
||||
run: brew update && brew install boost hidapi zmq libpgm miniupnpc ldns expat libunwind-headers protobuf
|
||||
- name: build
|
||||
run: |
|
||||
ccache --max-size=150M
|
||||
make -j3
|
||||
run: make -j3
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_TEMPDIR: C:\Users\runneradmin\.ccache-temp
|
||||
CCACHE_DIR: C:\Users\runneradmin\.ccache
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
@@ -46,128 +23,74 @@ jobs:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: C:\Users\runneradmin\.ccache
|
||||
key: ccache-windows-build-${{ github.sha }}
|
||||
restore-keys: ccache-windows-build-
|
||||
- uses: eine/setup-msys2@v2
|
||||
- uses: eine/setup-msys2@v1
|
||||
with:
|
||||
update: true
|
||||
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-ccache mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb git
|
||||
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb git
|
||||
- name: build
|
||||
run: |
|
||||
ccache --max-size=150M
|
||||
make release-static-win64 -j2
|
||||
run: make release-static-win64 -j2
|
||||
|
||||
build-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-ubuntu-build-${{ github.sha }}
|
||||
restore-keys: ccache-ubuntu-build-
|
||||
- name: remove bundled boost
|
||||
run: ${{env.REMOVE_BUNDLED_BOOST}}
|
||||
run: sudo rm -rf /usr/local/share/boost
|
||||
- name: set apt conf
|
||||
run: ${{env.APT_SET_CONF}}
|
||||
run: |
|
||||
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
- name: update apt
|
||||
run: sudo apt update
|
||||
- name: install monero dependencies
|
||||
run: ${{env.APT_INSTALL_LINUX}}
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler
|
||||
- name: build
|
||||
run: |
|
||||
ccache --max-size=150M
|
||||
make -j3
|
||||
run: make -j3
|
||||
|
||||
libwallet-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-ubuntu-libwallet-${{ github.sha }}
|
||||
restore-keys: ccache-ubuntu-libwallet-
|
||||
- name: remove bundled boost
|
||||
run: ${{env.REMOVE_BUNDLED_BOOST}}
|
||||
run: sudo rm -rf /usr/local/share/boost
|
||||
- name: set apt conf
|
||||
run: ${{env.APT_SET_CONF}}
|
||||
run: |
|
||||
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
- name: update apt
|
||||
run: sudo apt update
|
||||
- name: install monero dependencies
|
||||
run: ${{env.APT_INSTALL_LINUX}}
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler
|
||||
- name: build
|
||||
run: |
|
||||
ccache --max-size=150M
|
||||
cmake -DBUILD_GUI_DEPS=ON
|
||||
make -j3
|
||||
run: cmake -DBUILD_GUI_DEPS=ON && make -j3
|
||||
|
||||
test-ubuntu:
|
||||
needs: build-ubuntu
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: ccache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: test-ubuntu-ccache-${{ github.sha }}
|
||||
restore-keys: test-ubuntu-ccache-
|
||||
- name: remove bundled boost
|
||||
run: ${{env.REMOVE_BUNDLED_BOOST}}
|
||||
run: sudo rm -rf /usr/local/share/boost
|
||||
- name: set apt conf
|
||||
run: ${{env.APT_SET_CONF}}
|
||||
run: |
|
||||
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
- name: update apt
|
||||
run: sudo apt update
|
||||
- name: install monero dependencies
|
||||
run: ${{env.APT_INSTALL_LINUX}}
|
||||
- name: install Python dependencies
|
||||
run: pip install requests psutil monotonic
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler
|
||||
- name: install requests
|
||||
run: pip install requests
|
||||
- name: tests
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: ON
|
||||
run: |
|
||||
ccache --max-size=150M
|
||||
DIR_BUILD="build/ci/release"
|
||||
DIR_SRC="`pwd`"
|
||||
mkdir -p "${DIR_BUILD}" && cd "${DIR_BUILD}"
|
||||
cmake -S "${DIR_SRC}" -D ARCH="default" -D BUILD_SHARED_LIBS=ON -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release && make -j3 && make test
|
||||
|
||||
# ARCH="default" (not "native") ensures, that a different execution host can execute binaries compiled elsewhere.
|
||||
# BUILD_SHARED_LIBS=ON speeds up the linkage part a bit, reduces size, and is the only place where the dynamic linkage is tested.
|
||||
|
||||
source-archive:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: archive
|
||||
run: |
|
||||
pip install git-archive-all
|
||||
export VERSION="monero-$(git describe)"
|
||||
export OUTPUT="$VERSION.tar"
|
||||
echo "OUTPUT=$OUTPUT" >> $GITHUB_ENV
|
||||
/home/runner/.local/bin/git-archive-all --prefix "$VERSION/" --force-submodules "$OUTPUT"
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ env.OUTPUT }}
|
||||
path: /home/runner/work/monero/monero/${{ env.OUTPUT }}
|
||||
run: make release-test -j3
|
||||
|
||||
85
.github/workflows/depends.yml
vendored
85
.github/workflows/depends.yml
vendored
@@ -1,85 +0,0 @@
|
||||
name: ci/gh-actions/depends
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build-macos:
|
||||
runs-on: ubuntu-18.04
|
||||
env:
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
toolchain:
|
||||
- name: "RISCV 64bit"
|
||||
host: "riscv64-linux-gnu"
|
||||
packages: "python3 gperf g++-riscv64-linux-gnu"
|
||||
- name: "ARM v7"
|
||||
host: "arm-linux-gnueabihf"
|
||||
packages: "python3 gperf g++-arm-linux-gnueabihf"
|
||||
- name: "ARM v8"
|
||||
host: "aarch64-linux-gnu"
|
||||
packages: "python3 gperf g++-aarch64-linux-gnu"
|
||||
- name: "i686 Win"
|
||||
host: "i686-w64-mingw32"
|
||||
packages: "python3 g++-mingw-w64-i686 qttools5-dev-tools"
|
||||
- name: "i686 Linux"
|
||||
host: "i686-pc-linux-gnu"
|
||||
packages: "gperf cmake g++-multilib python3-zmq"
|
||||
- name: "Win64"
|
||||
host: "x86_64-w64-mingw32"
|
||||
packages: "cmake python3 g++-mingw-w64-x86-64 qttools5-dev-tools"
|
||||
- name: "x86_64 Linux"
|
||||
host: "x86_64-unknown-linux-gnu"
|
||||
packages: "gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
|
||||
- name: "Cross-Mac"
|
||||
host: "x86_64-apple-darwin11"
|
||||
packages: "cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git"
|
||||
osx_sdk: "10.11"
|
||||
- name: "x86_64 Freebsd"
|
||||
host: "x86_64-unknown-freebsd"
|
||||
packages: "clang-8 gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
|
||||
name: ${{ matrix.toolchain.name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: ccache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.ccache
|
||||
contrib/depends/built
|
||||
contrib/depends/sdk-sources
|
||||
key: ccache-${{ matrix.toolchain.host }}-${{ github.sha }}
|
||||
restore-keys: ccache-${{ matrix.toolchain.host }}-
|
||||
- name: set apt conf
|
||||
run: |
|
||||
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
- name: install dependencies
|
||||
run: sudo apt update; sudo apt -y install build-essential libtool cmake autotools-dev automake pkg-config bsdmainutils curl git ca-certificates ccache ${{ matrix.toolchain.packages }}
|
||||
- name: prepare apple-darwin11
|
||||
if: ${{ matrix.toolchain.host == 'x86_64-apple-darwin11' }}
|
||||
run: |
|
||||
mkdir -p contrib/depends/SDKs contrib/depends/sdk-sources
|
||||
if [ ! -f contrib/depends/sdk-sources/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz ]; then curl --location --fail https://bitcoincore.org/depends-sources/sdks/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz -o contrib/depends/sdk-sources/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz; fi
|
||||
if [ -f contrib/depends/sdk-sources/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz ]; then tar -C contrib/depends/SDKs -xf contrib/depends/sdk-sources/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz; fi
|
||||
- name: prepare w64-mingw32
|
||||
if: ${{ matrix.toolchain.host == 'x86_64-w64-mingw32' || matrix.toolchain.host == 'i686-w64-mingw32' }}
|
||||
run: |
|
||||
sudo update-alternatives --set ${{ matrix.toolchain.host }}-g++ $(which ${{ matrix.toolchain.host }}-g++-posix)
|
||||
sudo update-alternatives --set ${{ matrix.toolchain.host }}-gcc $(which ${{ matrix.toolchain.host }}-gcc-posix)
|
||||
- name: build
|
||||
run: |
|
||||
ccache --max-size=150M
|
||||
make depends target=${{ matrix.toolchain.host }} -j2
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ matrix.toolchain.host == 'x86_64-w64-mingw32' || matrix.toolchain.host == 'x86_64-apple-darwin11' || matrix.toolchain.host == 'x86_64-unknown-linux-gnu' }}
|
||||
with:
|
||||
name: ${{ matrix.toolchain.name }}
|
||||
path: |
|
||||
/home/runner/work/monero/monero/build/${{ matrix.toolchain.host }}/release/bin/monero-wallet-cli*
|
||||
/home/runner/work/monero/monero/build/${{ matrix.toolchain.host }}/release/bin/monerod*
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,7 +23,6 @@ cscope.po.out
|
||||
external/miniupnpc/Makefile
|
||||
miniupnpcstrings.h
|
||||
version/
|
||||
ClangBuildAnalyzerSession.txt
|
||||
# Created by https://www.gitignore.io
|
||||
|
||||
### C++ ###
|
||||
@@ -110,5 +109,3 @@ nbproject
|
||||
/testnet
|
||||
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.log
|
||||
|
||||
17
.gitmodules
vendored
17
.gitmodules
vendored
@@ -1,18 +1,19 @@
|
||||
[submodule "external/unbound"]
|
||||
path = external/unbound
|
||||
url = https://github.com/monero-project/unbound
|
||||
url = https://git.wownero.com/wownero/unbound
|
||||
branch = monero
|
||||
[submodule "external/miniupnp"]
|
||||
path = external/miniupnp
|
||||
url = https://github.com/miniupnp/miniupnp
|
||||
url = https://git.wownero.com/wownero/miniupnp
|
||||
branch = monero
|
||||
[submodule "external/rapidjson"]
|
||||
path = external/rapidjson
|
||||
url = https://github.com/Tencent/rapidjson
|
||||
[submodule "external/supercop"]
|
||||
path = external/supercop
|
||||
url = https://github.com/monero-project/supercop
|
||||
branch = monero
|
||||
url = https://git.wownero.com/wownero/rapidjson
|
||||
[submodule "external/RandomWOW"]
|
||||
path = external/RandomWOW
|
||||
url = https://git.wownero.com/wownero/RandomWOW
|
||||
branch = 1.1.9-wow
|
||||
branch = 1.1.8-wow
|
||||
[submodule "external/supercop"]
|
||||
path = external/supercop
|
||||
url = https://git.wownero.com/wownero/supercop
|
||||
branch = monero
|
||||
|
||||
66
.travis.yml
Normal file
66
.travis.yml
Normal file
@@ -0,0 +1,66 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
os: linux
|
||||
language: minimal
|
||||
cache:
|
||||
directories:
|
||||
- contrib/depends/built
|
||||
- contrib/depends/sdk-sources
|
||||
- $HOME/.ccache
|
||||
env:
|
||||
global:
|
||||
- MAKEJOBS=-j3
|
||||
- CCACHE_SIZE=100M
|
||||
- CCACHE_TEMPDIR=/tmp/.ccache-temp
|
||||
- CCACHE_COMPRESS=1
|
||||
- CCACHE_DIR=$HOME/.ccache
|
||||
- BASE_OUTDIR=$TRAVIS_BUILD_DIR/out
|
||||
- SDK_URL=https://bitcoincore.org/depends-sources/sdks
|
||||
- DOCKER_PACKAGES="build-essential libtool cmake autotools-dev automake pkg-config bsdmainutils curl git ca-certificates ccache"
|
||||
matrix:
|
||||
# RISCV 64bit
|
||||
- HOST=riscv64-linux-gnu PACKAGES="python3 gperf g++-riscv64-linux-gnu"
|
||||
# ARM v7
|
||||
- HOST=arm-linux-gnueabihf PACKAGES="python3 gperf g++-arm-linux-gnueabihf"
|
||||
# ARM v8
|
||||
- HOST=aarch64-linux-gnu PACKAGES="python3 gperf g++-aarch64-linux-gnu"
|
||||
# i686 Win
|
||||
- HOST=i686-w64-mingw32 DEP_OPTS="NO_QT=1" PACKAGES="python3 g++-mingw-w64-i686 qttools5-dev-tools" MAKEJOBS=-j2
|
||||
# i686 Linux
|
||||
- HOST=i686-pc-linux-gnu PACKAGES="gperf cmake g++-multilib python3-zmq"
|
||||
# Win64
|
||||
- HOST=x86_64-w64-mingw32 DEP_OPTS="NO_QT=1" PACKAGES="cmake python3 g++-mingw-w64-x86-64 qttools5-dev-tools"
|
||||
# x86_64 Linux
|
||||
- HOST=x86_64-unknown-linux-gnu PACKAGES="gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
|
||||
# Cross-Mac
|
||||
- HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git" OSX_SDK=10.11
|
||||
# x86_64 Freebsd
|
||||
- HOST=x86_64-unknown-freebsd PACKAGES="clang-8 gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
|
||||
|
||||
before_install:
|
||||
- export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
|
||||
install:
|
||||
- env | grep -E '^(CCACHE_|DISPLAY|CONFIG_SHELL)' | tee /tmp/env
|
||||
- if [[ $HOST = *-mingw32 ]]; then DOCKER_ADMIN="--cap-add SYS_ADMIN"; fi
|
||||
- DOCKER_ID=$(docker run $DOCKER_ADMIN -idt --mount type=bind,src=$TRAVIS_BUILD_DIR,dst=$TRAVIS_BUILD_DIR --mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR -w $TRAVIS_BUILD_DIR --env-file /tmp/env ubuntu:18.04)
|
||||
- DOCKER_EXEC="docker exec $DOCKER_ID"
|
||||
- if [ -n "$DPKG_ADD_ARCH" ]; then $DOCKER_EXEC dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi
|
||||
- travis_retry $DOCKER_EXEC apt-get update
|
||||
- travis_retry $DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES $DOCKER_PACKAGES
|
||||
before_script:
|
||||
- mkdir -p contrib/depends/SDKs contrib/depends/sdk-sources
|
||||
- if [ -n "$OSX_SDK" -a ! -f contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
|
||||
- if [ -n "$OSX_SDK" -a -f contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C contrib/depends/SDKs -xf contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
|
||||
- if [[ $HOST = *-mingw32 ]]; then $DOCKER_EXEC bash -c "update-alternatives --set $HOST-g++ \$(which $HOST-g++-posix)"; fi
|
||||
- if [[ $HOST = *-mingw32 ]]; then $DOCKER_EXEC bash -c "update-alternatives --set $HOST-gcc \$(which $HOST-gcc-posix)"; fi
|
||||
- if [ -z "$NO_DEPENDS" ]; then $DOCKER_EXEC bash -c "make $MAKEJOBS -C contrib/depends HOST=$HOST $DEP_OPTS"; fi
|
||||
script:
|
||||
- git submodule init && git submodule update
|
||||
- export TRAVIS_COMMIT_LOG=`git log --format=fuller -1`
|
||||
- OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
|
||||
- if [ -z "$NO_DEPENDS" ]; then $DOCKER_EXEC ccache --max-size=$CCACHE_SIZE; fi
|
||||
- $DOCKER_EXEC bash -c "mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=$TRAVIS_BUILD_DIR/contrib/depends/$HOST/share/toolchain.cmake .. && make $MAKEJOBS"
|
||||
- export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/contrib/depends/$HOST/lib
|
||||
after_script:
|
||||
- echo $TRAVIS_COMMIT_RANGE
|
||||
- echo $TRAVIS_COMMIT_LOG
|
||||
@@ -36,6 +36,10 @@ with additional exclusive IPv4 address(es).
|
||||
|
||||
## Usage
|
||||
|
||||
Anonymity networks have no seed nodes (the feature is still considered
|
||||
experimental), so a user must specify an address. If configured properly,
|
||||
additional peers can be found through typical p2p peerlist sharing.
|
||||
|
||||
### Outbound Connections
|
||||
|
||||
Connecting to an anonymous address requires the command line option
|
||||
@@ -50,9 +54,8 @@ separate process. On most systems the configuration will look like:
|
||||
which tells `monerod` that ".onion" p2p addresses can be forwarded to a socks
|
||||
proxy at IP 127.0.0.1 port 9050 with a max of 10 outgoing connections and
|
||||
".b32.i2p" p2p addresses can be forwarded to a socks proxy at IP 127.0.0.1 port
|
||||
9000 with the default max outgoing connections.
|
||||
|
||||
If desired, peers can be manually specified:
|
||||
9000 with the default max outgoing connections. Since there are no seed nodes
|
||||
for anonymity connections, peers must be manually specified:
|
||||
|
||||
```
|
||||
--add-exclusive-node rveahdfho7wo4b2m.onion:28083
|
||||
177
CMakeLists.txt
177
CMakeLists.txt
@@ -43,7 +43,7 @@ if (IOS)
|
||||
INCLUDE(CmakeLists_IOS.txt)
|
||||
endif()
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
message(STATUS "CMake version ${CMAKE_VERSION}")
|
||||
|
||||
project(monero)
|
||||
@@ -54,41 +54,6 @@ if (USE_CCACHE)
|
||||
else()
|
||||
message(STATUS "ccache deselected")
|
||||
endif()
|
||||
option (USE_COMPILATION_TIME_PROFILER "Use compilation time profiler (for CLang >= 9 only)" OFF)
|
||||
if (USE_COMPILATION_TIME_PROFILER)
|
||||
if (NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
message(FATAL_ERROR "The flag USE_COMPILATION_TIME_PROFILER is meant to be set only for CLang compiler!")
|
||||
endif()
|
||||
add_compile_options("-ftime-trace")
|
||||
endif()
|
||||
|
||||
if (${CMAKE_VERSION} VERSION_GREATER "3.0.0" AND CMAKE_MAKE_PROGRAM MATCHES "ninja")
|
||||
set(MONERO_PARALLEL_COMPILE_JOBS "" CACHE STRING "The maximum number of concurrent compilation jobs.")
|
||||
if (MONERO_PARALLEL_COMPILE_JOBS)
|
||||
set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${MONERO_PARALLEL_COMPILE_JOBS})
|
||||
set(CMAKE_JOB_POOL_COMPILE compile_job_pool)
|
||||
endif ()
|
||||
|
||||
set(MONERO_PARALLEL_LINK_JOBS "" CACHE STRING "The maximum number of concurrent link jobs.")
|
||||
if (MONERO_PARALLEL_LINK_JOBS)
|
||||
set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${MONERO_PARALLEL_LINK_JOBS})
|
||||
set(CMAKE_JOB_POOL_LINK link_job_pool)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
option (USE_CLANG_TIDY_C "Lint the code with clang-tidy - variant C" OFF)
|
||||
option (USE_CLANG_TIDY_CXX "Lint the code with clang-tidy - variant C++" OFF)
|
||||
if (USE_CLANG_TIDY_C AND USE_CLANG_TIDY_CXX)
|
||||
message(FATAL_ERROR "Enabling both USE_CLANG_TIDY_C and USE_CLANG_TIDY_CXX simultaneously crashes clang-tidy.")
|
||||
endif()
|
||||
if (USE_CLANG_TIDY_C OR USE_CLANG_TIDY_CXX)
|
||||
include(SetClangTidy)
|
||||
endif()
|
||||
if (USE_CLANG_TIDY_C)
|
||||
monero_clang_tidy("C")
|
||||
elseif (USE_CLANG_TIDY_CXX)
|
||||
monero_clang_tidy("CXX")
|
||||
endif()
|
||||
|
||||
# Job pool feature requires Ninja.
|
||||
if (${CMAKE_VERSION} VERSION_GREATER "3.0.0")
|
||||
@@ -161,48 +126,6 @@ function (add_definition_if_library_exists library function header var)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
option(RELINK_TARGETS "Relink targets, when just a dependant .so changed, but not its header?" OFF)
|
||||
function (monero_set_target_no_relink target)
|
||||
if (RELINK_TARGETS MATCHES OFF)
|
||||
# Will not relink the target, when just its dependant .so has changed, but not it's interface
|
||||
set_target_properties("${target}" PROPERTIES LINK_DEPENDS_NO_SHARED true)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
option(STRIP_TARGETS "Strip symbols from targets?" OFF)
|
||||
function (monero_set_target_strip target)
|
||||
if (STRIP_TARGETS)
|
||||
set_target_properties("${target}" PROPERTIES LINK_FLAGS_RELEASE -s)
|
||||
set_target_properties("${target}" PROPERTIES LINK_FLAGS_DEBUG -s)
|
||||
# Stripping from Debug might make sense if you're low on disk space, but want to test if debug version builds properly.
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function (monero_add_minimal_executable name)
|
||||
source_group("${name}"
|
||||
FILES
|
||||
${ARGN})
|
||||
|
||||
add_executable("${name}"
|
||||
${ARGN})
|
||||
monero_set_target_no_relink("${name}")
|
||||
monero_set_target_strip ("${name}")
|
||||
endfunction()
|
||||
|
||||
# Finds all headers in a directory and its subdirs, to be able to search for them and autosave in IDEs.
|
||||
#
|
||||
# Parameters:
|
||||
# - headers_found: Output variable, which will hold the found headers
|
||||
# - module_root_dir: The search path for the headers. Typically it will be the module's root dir, so "${CMAKE_CURRENT_SOURCE_DIR}" or a derivative of it.
|
||||
macro (monero_find_all_headers headers_found module_root_dir)
|
||||
file(GLOB ${headers_found}
|
||||
"${module_root_dir}/*.h*" # h* will include hpps as well.
|
||||
"${module_root_dir}/**/*.h*" # Any number of subdirs will be included.
|
||||
"${module_root_dir}/*.inl" # .inl is typically template code and is being treated as headers (it's being included).
|
||||
"${module_root_dir}/**/*.inl"
|
||||
)
|
||||
endmacro()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
|
||||
message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}")
|
||||
@@ -495,7 +418,7 @@ elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT MINGW)
|
||||
set(DEFAULT_STACK_TRACE ON)
|
||||
set(STACK_TRACE_LIB "easylogging++") # for diag output only
|
||||
set(LIBUNWIND_LIBRARIES "")
|
||||
elseif (ARM)
|
||||
elseif (ARM AND STATIC)
|
||||
set(DEFAULT_STACK_TRACE OFF)
|
||||
set(LIBUNWIND_LIBRARIES "")
|
||||
else()
|
||||
@@ -531,7 +454,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)")
|
||||
endif ()
|
||||
|
||||
if (APPLE AND NOT IOS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=x86-64 -fvisibility=default -std=c++11")
|
||||
if (NOT OPENSSL_ROOT_DIR)
|
||||
EXECUTE_PROCESS(COMMAND brew --prefix openssl
|
||||
OUTPUT_VARIABLE OPENSSL_ROOT_DIR
|
||||
@@ -560,44 +483,6 @@ add_definitions(-DAUTO_INITIALIZE_EASYLOGGINGPP)
|
||||
set(MONERO_GENERATED_HEADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated_include")
|
||||
include_directories(${MONERO_GENERATED_HEADERS_DIR})
|
||||
|
||||
option(COVERAGE "Enable profiling for test coverage report" OFF)
|
||||
if(COVERAGE)
|
||||
message(STATUS "Building with profiling for test coverage report")
|
||||
endif()
|
||||
macro (monero_enable_coverage)
|
||||
if(COVERAGE)
|
||||
foreach(COV_FLAG -fprofile-arcs -ftest-coverage --coverage)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COV_FLAG}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COV_FLAG}")
|
||||
endforeach()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function (monero_add_library name)
|
||||
monero_add_library_with_deps(NAME "${name}" SOURCES ${ARGN})
|
||||
endfunction()
|
||||
|
||||
function (monero_add_library_with_deps)
|
||||
cmake_parse_arguments(MONERO_ADD_LIBRARY "" "NAME" "DEPENDS;SOURCES" ${ARGN})
|
||||
source_group("${MONERO_ADD_LIBRARY_NAME}" FILES ${MONERO_ADD_LIBRARY_SOURCES})
|
||||
|
||||
# Define a ("virtual") object library and an actual library that links those
|
||||
# objects together. The virtual libraries can be arbitrarily combined to link
|
||||
# any subset of objects into one library archive. This is used for releasing
|
||||
# libwallet, which combines multiple components.
|
||||
set(objlib obj_${MONERO_ADD_LIBRARY_NAME})
|
||||
add_library(${objlib} OBJECT ${MONERO_ADD_LIBRARY_SOURCES})
|
||||
add_library("${MONERO_ADD_LIBRARY_NAME}" $<TARGET_OBJECTS:${objlib}>)
|
||||
monero_set_target_no_relink("${MONERO_ADD_LIBRARY_NAME}")
|
||||
monero_set_target_strip ("${MONERO_ADD_LIBRARY_NAME}")
|
||||
if (MONERO_ADD_LIBRARY_DEPENDS)
|
||||
add_dependencies(${objlib} ${MONERO_ADD_LIBRARY_DEPENDS})
|
||||
endif()
|
||||
set_property(TARGET "${MONERO_ADD_LIBRARY_NAME}" PROPERTY FOLDER "libs")
|
||||
target_compile_definitions(${objlib}
|
||||
PRIVATE $<TARGET_PROPERTY:${MONERO_ADD_LIBRARY_NAME},INTERFACE_COMPILE_DEFINITIONS>)
|
||||
endfunction ()
|
||||
|
||||
# Generate header for embedded translations
|
||||
# Generate header for embedded translations, use target toolchain if depends, otherwise use the
|
||||
# lrelease and lupdate binaries from the host
|
||||
@@ -607,7 +492,7 @@ ExternalProject_Add(generate_translations_header
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/translations"
|
||||
STAMP_DIR ${LRELEASE_PATH}
|
||||
CMAKE_ARGS -DLRELEASE_PATH=${LRELEASE_PATH}
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "")
|
||||
INSTALL_COMMAND cmake -E echo "")
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}/translations")
|
||||
add_subdirectory(external)
|
||||
|
||||
@@ -639,17 +524,6 @@ endif()
|
||||
# Trezor support check
|
||||
include(CheckTrezor)
|
||||
|
||||
# As of OpenBSD 6.8, -march=<anything> breaks the build
|
||||
function(set_default_arch)
|
||||
if (OPENBSD)
|
||||
set(ARCH default)
|
||||
else()
|
||||
set(ARCH native)
|
||||
endif()
|
||||
|
||||
set(ARCH ${ARCH} CACHE STRING "CPU to build for: -march value or 'default' to not pass -march at all")
|
||||
endfunction()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions("/bigobj /MP /W3 /GS- /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /DGTEST_HAS_TR1_TUPLE=0 /FIinline_c.h /D__SSE4_1__")
|
||||
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Dinline=__inline")
|
||||
@@ -663,7 +537,7 @@ if(MSVC)
|
||||
else()
|
||||
include(TestCXXAcceptsFlag)
|
||||
if (NOT ARCH)
|
||||
set_default_arch()
|
||||
set(ARCH native CACHE STRING "CPU to build for: -march value or 'default' to not pass -march at all")
|
||||
endif()
|
||||
message(STATUS "Building on ${CMAKE_SYSTEM_PROCESSOR} for ${ARCH}")
|
||||
if(ARCH STREQUAL "default")
|
||||
@@ -725,8 +599,8 @@ else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_FLAG}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_FLAG}")
|
||||
|
||||
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
if(ARM)
|
||||
set(WARNINGS "${WARNINGS} -Wno-error=inline-asm")
|
||||
endif()
|
||||
@@ -761,7 +635,13 @@ else()
|
||||
set(STATIC_ASSERT_CPP_FLAG "-Dstatic_assert=_Static_assert")
|
||||
endif()
|
||||
|
||||
monero_enable_coverage()
|
||||
option(COVERAGE "Enable profiling for test coverage report" 0)
|
||||
|
||||
if(COVERAGE)
|
||||
message(STATUS "Building with profiling for test coverage report")
|
||||
set(COVERAGE_FLAGS "-fprofile-arcs -ftest-coverage --coverage")
|
||||
endif()
|
||||
|
||||
# With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that
|
||||
# is fixed in the code (Issue #847), force compiler to be conservative.
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing")
|
||||
@@ -804,16 +684,10 @@ else()
|
||||
endif()
|
||||
|
||||
# linker
|
||||
if (NOT SANITIZE AND NOT OSSFUZZ AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND (CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1 OR NOT STATIC))))
|
||||
if (NOT SANITIZE AND NOT OSSFUZZ AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
|
||||
# PIE executables randomly crash at startup with ASAN
|
||||
# Windows binaries die on startup with PIE when compiled with GCC <9.x
|
||||
# Windows dynamically-linked binaries die on startup with PIE regardless of GCC version
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
# Clang does not support -pie flag
|
||||
add_linker_flag_if_supported("-Wl,-pie" LD_SECURITY_FLAGS)
|
||||
else()
|
||||
add_linker_flag_if_supported("-pie" LD_SECURITY_FLAGS)
|
||||
endif()
|
||||
add_linker_flag_if_supported(-pie LD_SECURITY_FLAGS)
|
||||
endif()
|
||||
add_linker_flag_if_supported(-Wl,-z,relro LD_SECURITY_FLAGS)
|
||||
add_linker_flag_if_supported(-Wl,-z,now LD_SECURITY_FLAGS)
|
||||
@@ -839,19 +713,12 @@ else()
|
||||
add_linker_flag_if_supported(-Wl,--high-entropy-va LD_SECURITY_FLAGS)
|
||||
endif()
|
||||
|
||||
# Warnings, that when ignored are so severe, that they can segfault or even UB any application.
|
||||
# Treat them as errors.
|
||||
add_c_flag_if_supported( -Werror=switch C_SECURITY_FLAGS)
|
||||
add_cxx_flag_if_supported(-Werror=switch CXX_SECURITY_FLAGS)
|
||||
add_c_flag_if_supported( -Werror=return-type C_SECURITY_FLAGS)
|
||||
add_cxx_flag_if_supported(-Werror=return-type CXX_SECURITY_FLAGS)
|
||||
|
||||
message(STATUS "Using C security hardening flags: ${C_SECURITY_FLAGS}")
|
||||
message(STATUS "Using C++ security hardening flags: ${CXX_SECURITY_FLAGS}")
|
||||
message(STATUS "Using linker security hardening flags: ${LD_SECURITY_FLAGS}")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${PIC_FLAG} ${C_SECURITY_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${PIC_FLAG} ${CXX_SECURITY_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${C_SECURITY_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${CXX_SECURITY_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_SECURITY_FLAGS} ${LD_BACKCOMPAT_FLAGS}")
|
||||
|
||||
# With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that
|
||||
@@ -969,7 +836,7 @@ else()
|
||||
endif()
|
||||
set(USE_LTO ${USE_LTO_DEFAULT} CACHE BOOL "Use Link-Time Optimization (Release mode only)")
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# There is a clang bug that does not allow to compile code that uses AES-NI intrinsics if -flto is enabled, so explicitly disable
|
||||
set(USE_LTO false)
|
||||
endif()
|
||||
@@ -1076,12 +943,10 @@ list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
|
||||
if (APPLE)
|
||||
if(DEPENDS)
|
||||
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework AppKit -framework IOKit")
|
||||
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
|
||||
else()
|
||||
find_library(COREFOUNDATION CoreFoundation)
|
||||
find_library(APPKIT AppKit)
|
||||
find_library(IOKIT IOKit)
|
||||
list(APPEND EXTRA_LIBRARIES ${APPKIT})
|
||||
list(APPEND EXTRA_LIBRARIES ${IOKIT})
|
||||
list(APPEND EXTRA_LIBRARIES ${COREFOUNDATION})
|
||||
endif()
|
||||
@@ -1116,7 +981,7 @@ if(ANDROID)
|
||||
set(ATOMIC libatomic.a)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=user-defined-warnings")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND ARCH_WIDTH EQUAL "32" AND NOT IOS AND NOT FREEBSD)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND ARCH_WIDTH EQUAL "32" AND NOT IOS AND NOT FREEBSD)
|
||||
find_library(ATOMIC atomic)
|
||||
if (ATOMIC_FOUND)
|
||||
list(APPEND EXTRA_LIBRARIES ${ATOMIC})
|
||||
|
||||
336
Dockerfile
336
Dockerfile
@@ -1,18 +1,28 @@
|
||||
# Multistage docker build, requires docker 17.05
|
||||
ARG DEBIAN_VERSION="${DEBIAN_VERSION:-stable-slim}"
|
||||
FROM debian:${DEBIAN_VERSION} as git-wow
|
||||
|
||||
# builder stage
|
||||
FROM ubuntu:16.04 as builder
|
||||
WORKDIR /data
|
||||
|
||||
RUN set -ex && \
|
||||
apt-get update && \
|
||||
apt-get --no-install-recommends --yes install \
|
||||
#Cmake
|
||||
ARG CMAKE_VERSION=3.14.6
|
||||
ARG CMAKE_VERSION_DOT=v3.14
|
||||
ARG CMAKE_HASH=4e8ea11cabe459308671b476469eace1622e770317a15951d7b55a82ccaaccb9
|
||||
## Boost
|
||||
ARG BOOST_VERSION=1_70_0
|
||||
ARG BOOST_VERSION_DOT=1.70.0
|
||||
ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778
|
||||
|
||||
ENV CFLAGS='-fPIC -O2 -g'
|
||||
ENV CXXFLAGS='-fPIC -O2 -g'
|
||||
ENV LDFLAGS='-static-libstdc++'
|
||||
|
||||
ENV BASE_DIR /usr/local
|
||||
|
||||
RUN apt-get update -qq && apt-get --no-install-recommends -yqq install \
|
||||
ca-certificates \
|
||||
cmake \
|
||||
g++ \
|
||||
make \
|
||||
pkg-config \
|
||||
graphviz \
|
||||
doxygen \
|
||||
git \
|
||||
curl \
|
||||
libtool-bin \
|
||||
@@ -21,191 +31,193 @@ RUN set -ex && \
|
||||
bzip2 \
|
||||
xsltproc \
|
||||
gperf \
|
||||
unzip
|
||||
|
||||
WORKDIR /usr/local
|
||||
|
||||
ENV CFLAGS='-fPIC'
|
||||
ENV CXXFLAGS='-fPIC'
|
||||
|
||||
#Cmake
|
||||
ARG CMAKE_VERSION=3.14.6
|
||||
ARG CMAKE_VERSION_DOT=v3.14
|
||||
ARG CMAKE_HASH=4e8ea11cabe459308671b476469eace1622e770317a15951d7b55a82ccaaccb9
|
||||
RUN set -ex \
|
||||
&& curl -s -O https://cmake.org/files/${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION}.tar.gz \
|
||||
unzip > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& echo "\e[32mbuilding: Cmake\e[39m" \
|
||||
&& set -ex \
|
||||
&& curl -s -O https://cmake.org/files/${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION}.tar.gz > /dev/null \
|
||||
&& echo "${CMAKE_HASH} cmake-${CMAKE_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf cmake-${CMAKE_VERSION}.tar.gz \
|
||||
&& cd cmake-${CMAKE_VERSION} \
|
||||
&& ./configure \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
## Boost
|
||||
ARG BOOST_VERSION=1_70_0
|
||||
ARG BOOST_VERSION_DOT=1.70.0
|
||||
ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778
|
||||
RUN set -ex \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& tar -xzf cmake-${CMAKE_VERSION}.tar.gz > /dev/null \
|
||||
&& cd cmake-${CMAKE_VERSION} || exit 1 \
|
||||
&& echo "\e[32mmatrix style build text redirected to /dev/null. This will take some time. Go ahead make some coffee and check your emails.\e[39m" \
|
||||
&& ./configure --prefix=$BASE_DIR > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/cmake-${CMAKE_VERSION} \
|
||||
&& rm -rf /data/cmake-${CMAKE_VERSION}.tar.gz \
|
||||
&& echo "\e[32mbuilding: Boost\e[39m" \
|
||||
&& set -ex \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 > /dev/null \
|
||||
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
|
||||
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& cd boost_${BOOST_VERSION} \
|
||||
&& ./bootstrap.sh \
|
||||
&& ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="$CFLAGS" cxxflags="$CXXFLAGS" stage
|
||||
ENV BOOST_ROOT /usr/local/boost_${BOOST_VERSION}
|
||||
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 > /dev/null \
|
||||
&& cd boost_${BOOST_VERSION} || exit 1 \
|
||||
&& ./bootstrap.sh > /dev/null \
|
||||
&& ./b2 -a install --prefix=$BASE_DIR --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="$CFLAGS" cxxflags="$CXXFLAGS" stage > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/boost_${BOOST_VERSION} \
|
||||
&& rm -rf /data/boost_${BOOST_VERSION}.tar.bz2
|
||||
|
||||
WORKDIR /data
|
||||
ENV BASE_DIR /usr/local
|
||||
|
||||
# OpenSSL
|
||||
ARG OPENSSL_VERSION=1.1.1i
|
||||
ARG OPENSSL_HASH=e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242
|
||||
RUN set -ex \
|
||||
&& curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \
|
||||
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \
|
||||
&& cd openssl-${OPENSSL_VERSION} \
|
||||
&& ./Configure linux-x86_64 no-shared --static "$CFLAGS" \
|
||||
&& make build_generated \
|
||||
&& make libcrypto.a \
|
||||
&& make install
|
||||
ENV OPENSSL_ROOT_DIR=/usr/local/openssl-${OPENSSL_VERSION}
|
||||
|
||||
ARG OPENSSL_VERSION=1.1.1
|
||||
ARG OPENSSL_FIX=g
|
||||
ARG OPENSSL_HASH=ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46
|
||||
# ZMQ
|
||||
ARG ZMQ_VERSION=v4.3.2
|
||||
ARG ZMQ_HASH=a84ffa12b2eb3569ced199660bac5ad128bff1f0
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} \
|
||||
&& cd libzmq \
|
||||
&& test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& ldconfig
|
||||
|
||||
# zmq.hpp
|
||||
ARG CPPZMQ_VERSION=v4.4.1
|
||||
ARG CPPZMQ_HASH=f5b36e563598d48fcc0d82e589d3596afef945ae
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/zeromq/cppzmq.git -b ${CPPZMQ_VERSION} \
|
||||
&& cd cppzmq \
|
||||
&& test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1 \
|
||||
&& mv *.hpp /usr/local/include
|
||||
|
||||
# Readline
|
||||
ARG READLINE_VERSION=8.0
|
||||
ARG READLINE_HASH=e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461
|
||||
RUN set -ex \
|
||||
&& curl -s -O https://ftp.gnu.org/gnu/readline/readline-${READLINE_VERSION}.tar.gz \
|
||||
&& echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf readline-${READLINE_VERSION}.tar.gz \
|
||||
&& cd readline-${READLINE_VERSION} \
|
||||
&& ./configure \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
# Sodium
|
||||
ARG SODIUM_VERSION=1.0.18
|
||||
ARG SODIUM_HASH=4f5e89fa84ce1d178a6765b8b46f2b6f91216677
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} \
|
||||
&& cd libsodium \
|
||||
|
||||
ENV CFLAGS='-fPIC -O2 -g'
|
||||
ENV CXXFLAGS='-fPIC -O2 -g'
|
||||
ENV LDFLAGS='-static-libstdc++'
|
||||
|
||||
RUN echo "\e[32mbuilding: Openssl\e[39m" \
|
||||
&& set -ex \
|
||||
&& curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz > /dev/null \
|
||||
# && curl -s -O https://www.openssl.org/source/old/${OPENSSL_VERSION}/openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz > /dev/null \
|
||||
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz > /dev/null \
|
||||
&& cd openssl-${OPENSSL_VERSION}${OPENSSL_FIX} || exit 1 \
|
||||
&& ./Configure --prefix=$BASE_DIR linux-x86_64 no-shared --static "$CFLAGS" > /dev/null \
|
||||
&& make build_generated > /dev/null \
|
||||
&& make libcrypto.a > /dev/null \
|
||||
&& echo "\e[32mblah, blah, shared libraries from the glib, something, something. Don't worry about it.\e[39m" \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/openssl-${OPENSSL_VERSION}${OPENSSL_FIX} \
|
||||
&& rm -rf /data/openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz \
|
||||
&& echo "\e[32mbuilding: ZMQ\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${ZMQ_VERSION} --single-branch --depth 1 https://github.com/zeromq/libzmq.git > /dev/null \
|
||||
&& cd libzmq || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \
|
||||
&& ./autogen.sh > /dev/null \
|
||||
&& ./configure --prefix=$BASE_DIR --enable-libunwind=no --enable-static --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& ldconfig > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/libzmq \
|
||||
&& echo "\e[32mbuilding: zmq.hpp\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${CPPZMQ_VERSION} --single-branch --depth 1 https://github.com/zeromq/cppzmq.git > /dev/null \
|
||||
&& cd cppzmq || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1 \
|
||||
&& mv *.hpp $BASE_DIR/include \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/cppzmq \
|
||||
&& echo "\e[32mbuilding: Readline\e[39m" \
|
||||
&& set -ex \
|
||||
&& curl -s -O https://ftp.gnu.org/gnu/readline/readline-${READLINE_VERSION}.tar.gz > /dev/null \
|
||||
&& echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf readline-${READLINE_VERSION}.tar.gz > /dev/null \
|
||||
&& cd readline-${READLINE_VERSION} || exit 1 \
|
||||
&& ./configure --prefix=$BASE_DIR > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/readline-${READLINE_VERSION} \
|
||||
&& rm -rf readline-${READLINE_VERSION}.tar.gz \
|
||||
&& echo "\e[32mbuilding: Sodium\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${SODIUM_VERSION} --single-branch --depth 1 https://github.com/jedisct1/libsodium.git > /dev/null \
|
||||
&& cd libsodium || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure \
|
||||
&& make \
|
||||
&& make check \
|
||||
&& make install
|
||||
&& ./configure --prefix=$BASE_DIR > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make check > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/libsodium
|
||||
|
||||
WORKDIR /data
|
||||
ENV BASE_DIR /usr/local
|
||||
|
||||
# Udev
|
||||
ARG UDEV_VERSION=v3.2.10
|
||||
ARG UDEV_HASH=be7068512c7512fa67c64fbff3472ab140c277c8
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/gentoo/eudev -b ${UDEV_VERSION} \
|
||||
&& cd eudev \
|
||||
&& test `git rev-parse HEAD` = ${UDEV_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
ARG UDEV_VERSION=v3.2.8
|
||||
ARG UDEV_HASH=d69f3f28348123ab7fa0ebac63ec2fd16800c5e0
|
||||
# Libusb
|
||||
ARG USB_VERSION=v1.0.22
|
||||
ARG USB_HASH=0034b2afdcdb1614e78edaa2a9e22d5936aeae5d
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/libusb/libusb.git -b ${USB_VERSION} \
|
||||
&& cd libusb \
|
||||
&& test `git rev-parse HEAD` = ${USB_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --disable-shared \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
# Hidapi
|
||||
ARG HIDAPI_VERSION=hidapi-0.8.0-rc1
|
||||
ARG HIDAPI_HASH=40cf516139b5b61e30d9403a48db23d8f915f52c
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/signal11/hidapi -b ${HIDAPI_VERSION} \
|
||||
&& cd hidapi \
|
||||
&& test `git rev-parse HEAD` = ${HIDAPI_HASH} || exit 1 \
|
||||
&& ./bootstrap \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
# Protobuf
|
||||
ARG PROTOBUF_VERSION=v3.7.1
|
||||
ARG PROTOBUF_HASH=6973c3a5041636c1d8dc5f7f6c8c1f3c15bc63d6
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/protocolbuffers/protobuf -b ${PROTOBUF_VERSION} \
|
||||
&& cd protobuf \
|
||||
&& test `git rev-parse HEAD` = ${PROTOBUF_HASH} || exit 1 \
|
||||
&& git submodule update --init --recursive \
|
||||
|
||||
ENV CFLAGS='-fPIC -O2 -g'
|
||||
ENV CXXFLAGS='-fPIC -O2 -g'
|
||||
ENV LDFLAGS='-static-libstdc++'
|
||||
|
||||
RUN echo "\e[32mbuilding: Udev\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${UDEV_VERSION} --single-branch --depth 1 https://github.com/gentoo/eudev > /dev/null \
|
||||
&& cd eudev || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${UDEV_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& ldconfig
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
&& ./configure --prefix=$BASE_DIR --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/eudev \
|
||||
&& echo "\e[32mbuilding: Libusb. Ahh, a dependency that shouldn't have been included in the codebase. Hardware wallets are way overrated.\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${USB_VERSION} --single-branch --depth 1 https://github.com/libusb/libusb.git > /dev/null \
|
||||
&& cd libusb || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${USB_HASH} || exit 1 \
|
||||
&& ./autogen.sh > /dev/null \
|
||||
&& ./configure --prefix=$BASE_DIR --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/libusb \
|
||||
&& echo "\e[32mbuilding: Hidapi\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${HIDAPI_VERSION} --single-branch --depth 1 https://github.com/signal11/hidapi > /dev/null \
|
||||
&& cd hidapi || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${HIDAPI_HASH} || exit 1 \
|
||||
&& ./bootstrap \
|
||||
&& ./configure --prefix=$BASE_DIR --enable-static --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/hidapi \
|
||||
&& echo "\e[32mbuilding: Protobuf <- fuck you protobuf, you worthless piece of shit!\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${PROTOBUF_VERSION} --single-branch --depth 1 https://github.com/protocolbuffers/protobuf > /dev/null \
|
||||
&& cd protobuf || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${PROTOBUF_HASH} || exit 1 \
|
||||
&& git submodule update --init --recursive > /dev/null \
|
||||
&& ./autogen.sh > /dev/null \
|
||||
&& ./configure --prefix=$BASE_DIR --enable-static --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& ldconfig \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/protobuf
|
||||
|
||||
WORKDIR /home
|
||||
ENV USE_SINGLE_BUILDDIR=1
|
||||
ARG NPROC
|
||||
RUN set -ex && \
|
||||
git submodule init && git submodule update && \
|
||||
rm -rf build && \
|
||||
if [ -z "$NPROC" ] ; \
|
||||
then make -j$(nproc) release-static ; \
|
||||
else make -j$NPROC release-static ; \
|
||||
fi
|
||||
|
||||
# runtime stage
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN set -ex && \
|
||||
apt-get update && \
|
||||
apt-get --no-install-recommends --yes install ca-certificates && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt
|
||||
COPY --from=builder /src/build/release/bin /usr/local/bin/
|
||||
|
||||
# Create wownero user
|
||||
RUN adduser --system --group --disabled-password wownero && \
|
||||
mkdir -p /wallet /home/wownero/.wownero && \
|
||||
chown -R wownero:wownero /home/wownero/.wownero && \
|
||||
chown -R wownero:wownero /wallet
|
||||
|
||||
# Contains the blockchain
|
||||
VOLUME /home/wownero/.wownero
|
||||
|
||||
# Generate your wallet via accessing the container and run:
|
||||
# cd /wallet
|
||||
# wownero-wallet-cli
|
||||
VOLUME /wallet
|
||||
|
||||
EXPOSE 34567
|
||||
EXPOSE 34568
|
||||
|
||||
# switch to user wownero
|
||||
USER wownero
|
||||
|
||||
ENTRYPOINT ["wownerod", "--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=34567", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=34568", "--non-interactive", "--confirm-external-bind"]
|
||||
# Wownero
|
||||
RUN echo "\e[32mbuilding: Wownero\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone https://git.wownero.com/wownero/wownero \
|
||||
&& cd wownero \
|
||||
&& make -j2 release-static-linux-x86_64 \
|
||||
&& echo "\e[32mdone building Wownero, binaries located in: /home/wownero/build/release/bin\e[39m"
|
||||
|
||||
6
Doxyfile
6
Doxyfile
@@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = doc
|
||||
# performance problems for the file system.
|
||||
# The default value is: NO.
|
||||
|
||||
CREATE_SUBDIRS = YES
|
||||
CREATE_SUBDIRS = NO
|
||||
|
||||
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
|
||||
# characters to appear in the names of generated files. If set to NO, non-ASCII
|
||||
@@ -754,7 +754,7 @@ WARN_LOGFILE =
|
||||
# spaces.
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = .
|
||||
INPUT = src
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
@@ -1552,7 +1552,7 @@ EXTRA_SEARCH_MAPPINGS =
|
||||
# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
|
||||
# The default value is: YES.
|
||||
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_LATEX = YES
|
||||
|
||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
|
||||
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||
|
||||
@@ -10,7 +10,7 @@ extensibility.
|
||||
One of the goals of this document is to clearly indicate what is being sent
|
||||
"on the wire" to identify metadata that could de-anonymize users over I2P/Tor.
|
||||
These issues will be addressed as they are found. See `ANONMITY_NETWORKS.md` in
|
||||
the `docs` folder for any outstanding issues.
|
||||
the top-level folder for any outstanding issues.
|
||||
|
||||
> This document does not currently list all data being sent by the monero
|
||||
> protocol, that portion is a work-in-progress. Please take the time to do it
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2014-2021, The Monero Project
|
||||
Copyright (c) 2014-2020, The Monero Project
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
||||
64
PKGBUILD
Normal file
64
PKGBUILD
Normal file
@@ -0,0 +1,64 @@
|
||||
# Maintainer: wowario <wowario[at]protonmail[dot]com>
|
||||
|
||||
pkgname=wownero-git
|
||||
pkgver=0.8.0.0
|
||||
pkgrel=1
|
||||
pkgdesc="Wownero: a fairly launched privacy-centric meme coin with no premine and a finite supply"
|
||||
license=('BSD')
|
||||
arch=('x86_64')
|
||||
url="https://wownero.org/"
|
||||
depends=('boost-libs' 'libunwind' 'openssl' 'readline' 'zeromq' 'pcsclite' 'hidapi' 'protobuf')
|
||||
makedepends=('git' 'cmake' 'boost')
|
||||
source=(
|
||||
"${pkgname}"::"git+https://github.com/wownero/wownero#tag=v${pkgver}"
|
||||
"git+https://github.com/monero-project/unbound.git"
|
||||
"git+https://github.com/monero-project/miniupnp.git"
|
||||
"git+https://github.com/Tencent/rapidjson.git"
|
||||
"git+https://github.com/trezor/trezor-common.git"
|
||||
"git+https://github.com/wownero/RandomWOW.git"
|
||||
"wownero.sysusers"
|
||||
"wownero.tmpfiles")
|
||||
sha512sums=('SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP')
|
||||
|
||||
prepare() {
|
||||
cd "${pkgname}"
|
||||
git submodule init
|
||||
git config submodule.external/unbound.url "$srcdir/unbound"
|
||||
git config submodule.external/miniupnp.url "$srcdir/miniupnp"
|
||||
git config submodule.external/rapidjson.url "$srcdir/rapidjson"
|
||||
git config submodule.external/RandomWOW.url "$srcdir/RandomWOW"
|
||||
git submodule update
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${pkgname}"
|
||||
mkdir -p build && cd build
|
||||
cmake -D BUILD_TESTS=OFF -D CMAKE_BUILD_TYPE=release -D ARCH=default ../
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
backup=('etc/wownerod.conf')
|
||||
|
||||
cd "${pkgname}"
|
||||
install -Dm644 "LICENSE" -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
||||
|
||||
install -Dm644 "utils/conf/wownerod.conf" "${pkgdir}/etc/wownerod.conf"
|
||||
install -Dm644 "utils/systemd/wownerod.service" "${pkgdir}/usr/lib/systemd/system/wownerod.service"
|
||||
install -Dm644 "../wownero.sysusers" "${pkgdir}/usr/lib/sysusers.d/wownero.conf"
|
||||
install -Dm644 "../wownero.tmpfiles" "${pkgdir}/usr/lib/tmpfiles.d/wownero.conf"
|
||||
|
||||
install -Dm755 "build/bin/wownero-wallet-cli" \
|
||||
"build/bin/wownero-wallet-rpc" \
|
||||
"build/bin/wownerod" \
|
||||
-t "${pkgdir}/usr/bin"
|
||||
}
|
||||
|
||||
# vim: ts=2 sw=2 et:
|
||||
71
README.md
71
README.md
@@ -1,34 +1,55 @@
|
||||
[](https://ci.wownero.com/wownero/wownero)
|
||||
# ~~Mo~~Wownero - Such privacy! Many coins! Wow! 🐕
|
||||
|
||||
Copyright (c) 2014-2021 The Monero Project.
|
||||
Copyright (c) 2014-2020 The Monero Project.
|
||||
Portions Copyright (c) 2012-2013 The Cryptonote developers.
|
||||
|
||||
# CyberWOW
|
||||
An Android pruned full node for Wownero
|
||||
|
||||
[<img src="https://git.wownero.com/wownero/meta/raw/branch/master/images/fdroid_badge.png"
|
||||
alt="Get it on F-Droid"
|
||||
height="80">](https://f-droid.org/en/packages/org.wownero.cyberwow/)
|
||||
<a href='https://play.google.com/store/apps/details?id=org.wownero.cyberwow'><img alt='Get it on Google Play' src='https://git.wownero.com/wownero/meta/raw/branch/master/images/google_badge.png' height='80'/></a>
|
||||
|
||||
# Wownerujo
|
||||
An Android Wallet for Wownero
|
||||
|
||||
[<img src="https://git.wownero.com/wownero/meta/raw/branch/master/images/fdroid_badge.png"
|
||||
alt="Get it on F-Droid"
|
||||
height="80">](https://f-droid.org/packages/com.wownero.wownerujo/)
|
||||
<a href='https://play.google.com/store/apps/details?id=com.wownero.wownerujo'><img alt='Get it on Google Play' src='https://git.wownero.com/wownero/meta/raw/branch/master/images/google_badge.png' height='80'/></a>
|
||||
|
||||
## Resources
|
||||
|
||||
- IRC: [OFTC #wownero](https://webchat.oftc.net/?channels=wownero)
|
||||
- Web: [wownero.org](https://wownero.org)
|
||||
- Web: [wownero.org](http://wownero.org)
|
||||
- Twitter: [@w0wn3r0](https://twitter.com/w0wn3r0)
|
||||
- Reddit: [/r/wownero](https://www.reddit.com/r/wownero)
|
||||
- Mail: [wownero@protonmail.com](mailto:wownero@protonmail.com)
|
||||
- Git: [git.wownero.com/wownero/wownero](https://git.wownero.com/wownero/wownero)
|
||||
- GitHub: [git.wownero.com/wownero/wownero](https://git.wownero.com/wownero/wownero)
|
||||
- IRC: [#wownero on Freenode](https://kiwiirc.com/client/irc.freenode.net/?nick=suchchatter|?#wownero)
|
||||
- Bitmessage Chan: wownero (`BM-2cSzWtrj2pzLva9GF1Jp2TYsnLjrnJpvba`)
|
||||
- Wownero Funding System: [funding.wownero.com](https://funding.wownero.com)
|
||||
- Wownero Forum: [forum.wownero.com](https://forum.wownero.com)
|
||||
- Discord: [discord.gg/ykZyAzJhDK](https://discord.com/invite/ykZyAzJhDK)
|
||||
- Discord: [discord.gg/abgaJbN](https://discord.gg/abgaJbN)
|
||||
- Telegram: [t.me/wownero](https://t.me/wownero)
|
||||
- Wowlet Desktop Wallet: [git.wownero.com/wowlet/wowlet](https://git.wownero.com/wowlet/wowlet/releases)
|
||||
- WOW Stash Web Wallet: [wowstash.app](https://wowstash.app)
|
||||
- Public Node Status: [monero.fail](https://monero.fail/?crypto=wownero)
|
||||
- Map of Nodes: [wownero.fyi](https://wownero.fyi)
|
||||
- Wownero Memes: [suchwow.xyz](https://suchwow.xyz/posts/top)
|
||||
- XMR/WOW Swap: [nero Swap](https://neroswap.com)
|
||||
- Mining Pools: [miningpoolstats.stream](https://miningpoolstats.stream/wownero)
|
||||
- Market Info: [coinmarketcap.com](https://coinmarketcap.com/currencies/wownero), [coingecko.com](https://www.coingecko.com/en/coins/wownero/usd)
|
||||
|
||||
### Blockchain Explorers
|
||||
Blockchain Explorers
|
||||
- https://explore.wownero.com
|
||||
- https://explorer.wowkira.com
|
||||
- http://wow5eqtzqvsg5jctqzg5g7uk3u62sfqiacj5x6lo4by7bvnj6jkvubyd.onion
|
||||
- https://wownero.club
|
||||
- https://explorer.wownero.fyi
|
||||
- https://wownero.xmrauctions.com
|
||||
|
||||
Free Public Nodes
|
||||
- global.wownodes.com:34568 (Global)
|
||||
- node.suchwow.xyz:34568 (US)
|
||||
- wow.pwned.systems:34568 (NL)
|
||||
- wowbux.org:34568 (CA)
|
||||
- wowbuxx535x4exuexja2xfezpwcyznxkofui4ndjiectj4yuh2xheiid.onion:34568
|
||||
|
||||
Tor Peers
|
||||
- wowp2p5gelm6vhl2d5tvfqills63jilgy6hkvlrqljooov5ktaxgqdad.onion
|
||||
- f3moshycuklu3mb3wnlfjwn26nsgzreqtfzfuyjjk46u7jqxlhf7d5id.onion
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -41,13 +62,10 @@ Wownero is a 100% community-sponsored endeavor. Supporting services are also gra
|
||||
[<img src="https://git.wownero.com/wownero/meta/raw/branch/master/images/macstadium.png"
|
||||
alt="MacStadium"
|
||||
height="100">](https://www.macstadium.com)
|
||||
[<img src="https://git.wownero.com/wownero/meta/raw/branch/master/images/jetbrains.png"
|
||||
alt="JetBrains"
|
||||
height="100">](https://www.jetbrains.com)
|
||||
|
||||
Developers are volunteers doing this mostly for shits and giggles. If you would like to support our shenanigans and stimulant addictions, please consider donating to [WFS proposals](https://funding.wownero.com/proposals) or the dev slush fund.
|
||||
|
||||
### Donation Addresses
|
||||
Donation Addresses
|
||||
|
||||
WOW: `Wo3MWeKwtA918DU4c69hVSNgejdWFCRCuWjShRY66mJkU2Hv58eygJWDJS1MNa2Ge5M1WjUkGHuLqHkweDxwZZU42d16v94mP`
|
||||
|
||||
@@ -59,12 +77,6 @@ XMR: `44SQVPGLufPasUcuUQSZiF5c9BFzjcP8ucDxzzFDgLf1VkCEFaidJ3u2AhSKMhPLKA3jc2iS8w
|
||||
|
||||
BTC: `bc1qcw9zglp3fxyl25zswemw7jczlqryms2lsmu464`
|
||||
|
||||
### Open Collective
|
||||
|
||||
Open Collective is an online funding platform for open source software and collaborative communities. The platform brings together legal entities that act as a “Fiscal Host”, “Collectives” (unincorporated, community-based projects), and individuals interested in supporting projects with donations. Fiscal hosts hold donations for collectives in trust and handle all the taxes and legal stuff.
|
||||
|
||||
Wownero is hosted by Open Collective Europe, a Brussels-based non-profit that hosts many other collectives, such as Manjaro, EndeavourOS, Xfce, and peertube.social. If you would like donate to the Wownero Project using this method, you can check out our [Wownero - Open Collective](https://opencollective.com/wownero) page.
|
||||
|
||||
## Release staging and Contributing
|
||||
|
||||
**Anyone is welcome to contribute to Wownero's codebase!**
|
||||
@@ -73,7 +85,7 @@ If you have a fix or code change, feel free to submit it as a pull request. Ahea
|
||||
|
||||
Things to Do, Work in Progress, and Help Wanted tasks are tracked in the [Meta](https://git.wownero.com/wownero/meta/issues) repo.
|
||||
|
||||
Join `#wownero-dev` on IRC OFTC to participate in development conversation.
|
||||
Join `#wownero-dev` on IRC freenode to participate in development conversation.
|
||||
|
||||
## Scheduled software upgrades
|
||||
|
||||
@@ -90,8 +102,7 @@ Dates are provided in the format YYYY-MM-DD.
|
||||
| 114,969 | 2019-06-14 | F For Fappening | v0.6.1.0 | v0.6.1.2 | RandomWOW, new block weight algorithm, slightly more efficient RingCT format
|
||||
| 160,777 | 2019-11-20 | Gaping Goatse | v0.7.0.0 | v0.7.1.0 | Only allow >= 2 outputs, change to the block median used to calculate penalty, rct sigs in coinbase forbidden, 4 unlock time as protocol rule
|
||||
| - | 2020-06-28 | Hallucinogenic Hypnotoad | v0.8.0.0 | v0.8.0.2 | Dandelion++ support
|
||||
| 253,999 | 2020-10-09 | Illiterate Illuminati | v0.9.0.0 | v0.9.3.3 | Dynamic coinbase unlock (up to 1 mo.), Deterministic unlock times, Enforce maximum coinbase amount, show_qr_code wallet command, CLSAG
|
||||
| 331,170 | 2021-07-04 | Junkie Jeff | v0.10.0.0 | v0.10.0.0 | Bulletproofs+, Miner Block Header Signing, Vote by Block, Change coinbase unlock time to 1 day, Reset difficulty and switch back to Monero's difficulty algorithm
|
||||
| 253,999 | 2020-10-09 | Illiterate Illuminati | v0.9.0.0 | v0.9.0.2 | Dynamic coinbase unlock (up to 1 mo.), Deterministic unlock times, Enforce maximum coinbase amount, show_qr_code wallet command, CLSAG
|
||||
|
||||
X's indicate that these details have not been determined as of commit date.
|
||||
|
||||
@@ -105,7 +116,7 @@ Packages are available for
|
||||
|
||||
yay -S wownero-git
|
||||
|
||||
* Gentoo - Russian hacking tool
|
||||
* Gentoo
|
||||
|
||||
emerge --noreplace eselect-repository
|
||||
eselect repository enable monero
|
||||
|
||||
@@ -15,7 +15,6 @@ macro(CHECK_LINKER_FLAG flag VARIABLE)
|
||||
${_cle_source}
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${flag}
|
||||
CMAKE_FLAGS
|
||||
"-DCMAKE_EXE_LINKER_FLAGS=${flag}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
unset(_cle_source)
|
||||
set(CMAKE_C_FLAGS ${saved_CMAKE_C_FLAGS})
|
||||
|
||||
@@ -91,7 +91,7 @@ endif()
|
||||
|
||||
# Protobuf compilation test
|
||||
if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
|
||||
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_CURRENT_LIST_DIR}" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
|
||||
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_SOURCE_DIR}/cmake" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_SOURCE_DIR}/cmake/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
|
||||
if(RET)
|
||||
message(STATUS "Protobuf test generation failed: ${OUT} ${ERR}")
|
||||
endif()
|
||||
@@ -100,7 +100,7 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
SOURCES
|
||||
"${CMAKE_BINARY_DIR}/test-protobuf.pb.cc"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/test-protobuf.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/cmake/test-protobuf.cpp"
|
||||
CMAKE_FLAGS
|
||||
"-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}"
|
||||
"-DCMAKE_CXX_STANDARD=11"
|
||||
|
||||
@@ -42,19 +42,12 @@
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if (CCACHE_FOUND)
|
||||
# Try to compile a test program with ccache, in order to verify if it really works. (needed on exotic setups)
|
||||
set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp")
|
||||
file(WRITE "${TEST_PROJECT}/CMakeLists.txt" [=[
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(test)
|
||||
option (CCACHE "")
|
||||
file(WRITE "${CMAKE_SOURCE_DIR}/test.cpp" "int main() { return 0; }")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE}")
|
||||
add_executable(test test.cpp)
|
||||
]=])
|
||||
try_compile(RET "${TEST_PROJECT}/build" "${TEST_PROJECT}" "test" CMAKE_FLAGS -DCCACHE="${CCACHE_FOUND}")
|
||||
unset(TEST_PROJECT)
|
||||
if (${RET})
|
||||
# Create a temporary file with a simple program.
|
||||
set(TEMP_CPP_FILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/test-program.cpp")
|
||||
file(WRITE "${TEMP_CPP_FILE}" "int main() { return 0; }")
|
||||
# And run the found ccache on it.
|
||||
execute_process(COMMAND "${CCACHE_FOUND}" "${CMAKE_CXX_COMPILER}" "${TEMP_CPP_FILE}" RESULT_VARIABLE RET)
|
||||
if (${RET} EQUAL 0)
|
||||
# Success
|
||||
message(STATUS "Found usable ccache: ${CCACHE_FOUND}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND}")
|
||||
|
||||
@@ -134,7 +134,7 @@ if ( LibUSB_FOUND )
|
||||
|
||||
try_compile(LibUSB_COMPILE_TEST_PASSED
|
||||
${CMAKE_BINARY_DIR}
|
||||
"${CMAKE_CURRENT_LIST_DIR}/test-libusb-version.c"
|
||||
"${CMAKE_SOURCE_DIR}/cmake/test-libusb-version.c"
|
||||
CMAKE_FLAGS
|
||||
"-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}"
|
||||
"-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}"
|
||||
|
||||
@@ -48,21 +48,29 @@ function (get_version_tag_from_git GIT)
|
||||
message(STATUS "You are currently on commit ${COMMIT}")
|
||||
|
||||
# Get all the tags
|
||||
execute_process(COMMAND "${GIT}" tag -l --points-at HEAD
|
||||
execute_process(COMMAND "${GIT}" rev-list --tags --max-count=1 --abbrev-commit
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
RESULT_VARIABLE RET
|
||||
OUTPUT_VARIABLE TAG
|
||||
OUTPUT_VARIABLE TAGGEDCOMMIT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# Check if we're building that tagged commit or a different one
|
||||
if(TAG)
|
||||
message(STATUS "You are building a tagged release")
|
||||
set(VERSIONTAG "release")
|
||||
set(VERSION_IS_RELEASE "true")
|
||||
else()
|
||||
message(STATUS "You are ahead of or behind a tagged release")
|
||||
if(NOT TAGGEDCOMMIT)
|
||||
message(WARNING "Cannot determine most recent tag. Make sure that you are building either from a Git working tree or from a source archive.")
|
||||
set(VERSIONTAG "${COMMIT}")
|
||||
set(VERSION_IS_RELEASE "false")
|
||||
else()
|
||||
message(STATUS "The most recent tag was at ${TAGGEDCOMMIT}")
|
||||
|
||||
# Check if we're building that tagged commit or a different one
|
||||
if(COMMIT STREQUAL TAGGEDCOMMIT)
|
||||
message(STATUS "You are building a tagged release")
|
||||
set(VERSIONTAG "release")
|
||||
set(VERSION_IS_RELEASE "true")
|
||||
else()
|
||||
message(STATUS "You are ahead of or behind a tagged release")
|
||||
set(VERSIONTAG "${COMMIT}")
|
||||
set(VERSION_IS_RELEASE "false")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
# Copyright (c) 2014-2020, The Monero Project
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification, are
|
||||
# permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other
|
||||
# materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_CLANG_TIDY.html
|
||||
# This module sets the following variables:
|
||||
# CMAKE_C_CLANG_TIDY
|
||||
# CMAKE_CXX_CLANG_TIDY
|
||||
# when clang-tidy is found in PATH. Afterwards, the code is being linted by the tool.
|
||||
# The checks to be enabled can be manipulated with the variable MONERO_CLANG_TIDY_CHECKS
|
||||
|
||||
macro (monero_clang_tidy LANGUAGE)
|
||||
set(TOOL_NAME "clang-tidy")
|
||||
set(MONERO_CLANG_TIDY_MIN_VERSION "3.6")
|
||||
if(${CMAKE_VERSION} VERSION_LESS "${MONERO_CLANG_TIDY_MIN_VERSION}")
|
||||
message(FATAL_ERROR "Sorry, ${TOOL_NAME} is available for CMake from version ${MONERO_CLANG_TIDY_MIN_VERSION}")
|
||||
else()
|
||||
message(STATUS "Trying to enable ${TOOL_NAME}")
|
||||
find_program(MONERO_CLANG_BIN ${TOOL_NAME})
|
||||
if(NOT MONERO_CLANG_BIN)
|
||||
message(FATAL_ERROR "${TOOL_NAME} not found! Try running: sudo apt install ${TOOL_NAME}")
|
||||
else()
|
||||
message(STATUS "Found ${MONERO_CLANG_BIN}")
|
||||
set(MONERO_CLANG_TIDY_CHECKS
|
||||
-header-filter=.; # By default the headers are excluded. This line enables them.
|
||||
-checks=*; # Currently enabling all checks
|
||||
# An example of selectively enabling checks:
|
||||
#-checks=bugprone-*,cppcoreguidelines-avoid-goto # Have to be in one line :(
|
||||
)
|
||||
# Current list of checks is avaibale under:
|
||||
# https://clang.llvm.org/extra/clang-tidy/
|
||||
if (${LANGUAGE} STREQUAL "C")
|
||||
set(CMAKE_C_CLANG_TIDY
|
||||
${MONERO_CLANG_BIN}; # Mind the semicolon
|
||||
${MONERO_CLANG_TIDY_CHECKS}
|
||||
)
|
||||
elseif (${LANGUAGE} STREQUAL "CXX")
|
||||
set(CMAKE_CXX_CLANG_TIDY
|
||||
${MONERO_CLANG_BIN}; # Mind the semicolon
|
||||
${MONERO_CLANG_TIDY_CHECKS}
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "${TOOL_NAME}: Unsupported language: ${LANGUAGE}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
function (write_version tag)
|
||||
set(VERSIONTAG "${tag}" CACHE STRING "The tag portion of the Monero software version" FORCE)
|
||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/../src/version.cpp.in" "${CMAKE_BINARY_DIR}/version.cpp")
|
||||
configure_file("${CMAKE_SOURCE_DIR}/src/version.cpp.in" "${CMAKE_BINARY_DIR}/version.cpp")
|
||||
endfunction ()
|
||||
|
||||
find_package(Git QUIET)
|
||||
|
||||
@@ -26,6 +26,5 @@
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
monero_enable_coverage()
|
||||
add_subdirectory(epee)
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ brew "miniupnpc"
|
||||
brew "readline"
|
||||
brew "ldns"
|
||||
brew "expat"
|
||||
brew "ccache"
|
||||
brew "doxygen"
|
||||
brew "graphviz"
|
||||
brew "libunwind-headers"
|
||||
|
||||
@@ -10,8 +10,8 @@ HOST ?= $(BUILD)
|
||||
PATCHES_PATH = $(BASEDIR)/patches
|
||||
BASEDIR = $(CURDIR)
|
||||
HASH_LENGTH:=11
|
||||
DOWNLOAD_CONNECT_TIMEOUT:=30
|
||||
DOWNLOAD_RETRIES:=5
|
||||
DOWNLOAD_CONNECT_TIMEOUT:=10
|
||||
DOWNLOAD_RETRIES:=3
|
||||
HOST_ID_SALT ?= salt
|
||||
BUILD_ID_SALT ?= salt
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package=boost
|
||||
$(package)_version=1_64_0
|
||||
$(package)_download_path=https://downloads.sourceforge.net/project/boost/boost/1.64.0/
|
||||
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/
|
||||
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332
|
||||
$(package)_dependencies=libiconv
|
||||
|
||||
@@ -1,31 +1,36 @@
|
||||
package=openssl
|
||||
$(package)_version=1.1.1k
|
||||
$(package)_download_path=https://www.openssl.org/source
|
||||
$(package)_version=1.0.2r
|
||||
$(package)_download_path=https://ftp.openssl.org/source/old/1.0.2
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5
|
||||
$(package)_sha256_hash=ae51d08bba8a83958e894946f15303ff894d75c2b8bbd44a852b64e3fe11d0d6
|
||||
$(package)_patches=fix_arflags.patch
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_env=AR="$($(package)_ar)" ARFLAGS=$($(package)_arflags) RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||
$(package)_config_env_arm_android=ANDROID_NDK_HOME="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
|
||||
$(package)_config_env_aarch64_android=ANDROID_NDK_HOME="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
|
||||
$(package)_build_env_arm_android=ANDROID_NDK_HOME="$(host_prefix)/native"
|
||||
$(package)_build_env_aarch64_android=ANDROID_NDK_HOME="$(host_prefix)/native"
|
||||
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl
|
||||
$(package)_config_opts+=no-capieng
|
||||
$(package)_config_opts+=no-dso
|
||||
$(package)_config_opts+=no-dtls1
|
||||
$(package)_config_opts+=no-ec_nistp_64_gcc_128
|
||||
$(package)_config_opts+=no-gost
|
||||
$(package)_config_opts+=no-gmp
|
||||
$(package)_config_opts+=no-heartbeats
|
||||
$(package)_config_opts+=no-jpake
|
||||
$(package)_config_opts+=no-krb5
|
||||
$(package)_config_opts+=no-libunbound
|
||||
$(package)_config_opts+=no-md2
|
||||
$(package)_config_opts+=no-rc5
|
||||
$(package)_config_opts+=no-rdrand
|
||||
$(package)_config_opts+=no-rfc3779
|
||||
$(package)_config_opts+=no-rsax
|
||||
$(package)_config_opts+=no-sctp
|
||||
$(package)_config_opts+=no-sha0
|
||||
$(package)_config_opts+=no-shared
|
||||
$(package)_config_opts+=no-ssl-trace
|
||||
$(package)_config_opts+=no-ssl2
|
||||
$(package)_config_opts+=no-ssl3
|
||||
$(package)_config_opts+=no-static_engine
|
||||
$(package)_config_opts+=no-store
|
||||
$(package)_config_opts+=no-unit-test
|
||||
$(package)_config_opts+=no-weak-ssl-ciphers
|
||||
$(package)_config_opts+=no-zlib
|
||||
@@ -37,8 +42,8 @@ $(package)_config_opts_x86_64_linux=linux-x86_64
|
||||
$(package)_config_opts_i686_linux=linux-generic32
|
||||
$(package)_config_opts_arm_linux=linux-generic32
|
||||
$(package)_config_opts_aarch64_linux=linux-generic64
|
||||
$(package)_config_opts_arm_android=--static android-arm
|
||||
$(package)_config_opts_aarch64_android=--static android-arm64
|
||||
$(package)_config_opts_arm_android=--static android-armv7 no-asm
|
||||
$(package)_config_opts_aarch64_android=--static android no-asm
|
||||
$(package)_config_opts_riscv64_linux=linux-generic64
|
||||
$(package)_config_opts_mipsel_linux=linux-generic32
|
||||
$(package)_config_opts_mips_linux=linux-generic32
|
||||
@@ -50,8 +55,10 @@ $(package)_config_opts_x86_64_freebsd=BSD-x86_64
|
||||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
sed -i.old 's|"engines", "apps", "test", "util", "tools", "fuzz"|"engines", "tools"|' Configure && \
|
||||
sed -i -e 's|cflags --sysroot.*",|cflags",|' Configurations/15-android.conf
|
||||
sed -i.old "/define DATE/d" util/mkbuildinf.pl && \
|
||||
sed -i.old "s|engines apps test|engines|" Makefile.org && \
|
||||
sed -i -e "s/-mandroid //" Configure && \
|
||||
patch < $($(package)_patch_dir)/fix_arflags.patch
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
@@ -63,7 +70,7 @@ define $(package)_build_cmds
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) -j1 install_sw
|
||||
$(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw
|
||||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
PACKAGE=qt
|
||||
$(package)_version=5.15.1
|
||||
$(package)_download_path=https://download.qt.io/official_releases/qt/5.15/$($(package)_version)/submodules
|
||||
$(package)_suffix=everywhere-src-$($(package)_version).tar.xz
|
||||
$(package)_version=5.7.1
|
||||
$(package)_download_path=http://linorg.usp.br/Qt/archive/qt/5.7/5.7.1/submodules
|
||||
$(package)_suffix=opensource-src-$($(package)_version).tar.gz
|
||||
$(package)_file_name=qtbase-$($(package)_suffix)
|
||||
$(package)_sha256_hash=33960404d579675b7210de103ed06a72613bfc4305443e278e2d32a3eb1f3d8c
|
||||
$(package)_sha256_hash=95f83e532d23b3ddbde7973f380ecae1bac13230340557276f75f2e37984e410
|
||||
$(package)_build_subdir=qtbase
|
||||
$(package)_qt_libs=corelib
|
||||
$(package)_patches=fix_qt_pkgconfig.patch fix_no_printer.patch fix_rcc_determinism.patch no-xlib.patch
|
||||
$(package)_patches=pidlist_absolute.patch fix_qt_pkgconfig.patch qfixed-coretext.patch
|
||||
|
||||
$(package)_qttranslations_file_name=qttranslations-$($(package)_suffix)
|
||||
$(package)_qttranslations_sha256_hash=46e0c0e3a511fbcc803a4146204062e47f6ed43b34d98a3c27372a03b8746bd8
|
||||
$(package)_qttranslations_sha256_hash=3a15aebd523c6d89fb97b2d3df866c94149653a26d27a00aac9b6d3020bc5a1d
|
||||
|
||||
$(package)_qttools_file_name=qttools-$($(package)_suffix)
|
||||
$(package)_qttools_sha256_hash=c98ee5f0f980bf68cbf0c94d62434816a92441733de50bd9adbe9b9055f03498
|
||||
$(package)_qttools_sha256_hash=22d67de915cb8cd93e16fdd38fa006224ad9170bd217c2be1e53045a8dd02f0f
|
||||
|
||||
$(package)_extra_sources = $($(package)_qttranslations_file_name)
|
||||
$(package)_extra_sources += $($(package)_qttools_file_name)
|
||||
@@ -24,26 +24,28 @@ $(package)_config_opts += -bindir $(build_prefix)/bin
|
||||
$(package)_config_opts += -c++std c++11
|
||||
$(package)_config_opts += -confirm-license
|
||||
$(package)_config_opts += -dbus-runtime
|
||||
$(package)_config_opts += -hostprefix $(build_prefix)
|
||||
$(package)_config_opts += -no-compile-examples
|
||||
$(package)_config_opts += -no-alsa
|
||||
$(package)_config_opts += -no-audio-backend
|
||||
$(package)_config_opts += -no-cups
|
||||
$(package)_config_opts += -no-egl
|
||||
$(package)_config_opts += -no-eglfs
|
||||
$(package)_config_opts += -no-evdev
|
||||
$(package)_config_opts += -no-gui
|
||||
$(package)_config_opts += -no-feature-style-windowsmobile
|
||||
$(package)_config_opts += -no-feature-style-windowsce
|
||||
$(package)_config_opts += -no-freetype
|
||||
$(package)_config_opts += -no-gif
|
||||
$(package)_config_opts += -no-glib
|
||||
$(package)_config_opts += -no-gstreamer
|
||||
$(package)_config_opts += -no-icu
|
||||
$(package)_config_opts += -no-ico
|
||||
$(package)_config_opts += -no-iconv
|
||||
$(package)_config_opts += -no-kms
|
||||
$(package)_config_opts += -no-linuxfb
|
||||
$(package)_config_opts += -no-libjpeg
|
||||
$(package)_config_opts += -no-libudev
|
||||
$(package)_config_opts += -no-mitshm
|
||||
$(package)_config_opts += -no-mtdev
|
||||
$(package)_config_opts += -no-pulseaudio
|
||||
$(package)_config_opts += -no-openvg
|
||||
$(package)_config_opts += -no-reduce-relocations
|
||||
$(package)_config_opts += -no-qml-debug
|
||||
$(package)_config_opts += -no-sql-db2
|
||||
$(package)_config_opts += -no-sql-ibase
|
||||
$(package)_config_opts += -no-sql-oci
|
||||
@@ -54,6 +56,8 @@ $(package)_config_opts += -no-sql-psql
|
||||
$(package)_config_opts += -no-sql-sqlite
|
||||
$(package)_config_opts += -no-sql-sqlite2
|
||||
$(package)_config_opts += -no-use-gold-linker
|
||||
$(package)_config_opts += -no-xinput2
|
||||
$(package)_config_opts += -no-xrender
|
||||
$(package)_config_opts += -nomake examples
|
||||
$(package)_config_opts += -nomake tests
|
||||
$(package)_config_opts += -opensource
|
||||
@@ -61,46 +65,25 @@ $(package)_config_opts += -no-openssl
|
||||
$(package)_config_opts += -optimized-qmake
|
||||
$(package)_config_opts += -pch
|
||||
$(package)_config_opts += -pkg-config
|
||||
$(package)_config_opts += -prefix $(host_prefix)
|
||||
$(package)_config_opts += -no-libpng
|
||||
$(package)_config_opts += -no-libjpeg
|
||||
$(package)_config_opts += -qt-pcre
|
||||
$(package)_config_opts += -qt-harfbuzz
|
||||
$(package)_config_opts += -no-zlib
|
||||
$(package)_config_opts += -reduce-exports
|
||||
$(package)_config_opts += -static
|
||||
$(package)_config_opts += -silent
|
||||
$(package)_config_opts += -v
|
||||
$(package)_config_opts += -no-feature-bearermanagement
|
||||
$(package)_config_opts += -no-feature-colordialog
|
||||
$(package)_config_opts += -no-feature-dial
|
||||
$(package)_config_opts += -no-feature-filesystemwatcher
|
||||
$(package)_config_opts += -no-feature-fontcombobox
|
||||
$(package)_config_opts += -no-feature-ftp
|
||||
$(package)_config_opts += -no-feature-image_heuristic_mask
|
||||
$(package)_config_opts += -no-feature-keysequenceedit
|
||||
$(package)_config_opts += -no-feature-lcdnumber
|
||||
$(package)_config_opts += -no-feature-pdf
|
||||
$(package)_config_opts += -no-feature-printdialog
|
||||
$(package)_config_opts += -no-feature-printer
|
||||
$(package)_config_opts += -no-feature-printpreviewdialog
|
||||
$(package)_config_opts += -no-feature-printpreviewwidget
|
||||
$(package)_config_opts += -no-feature-sessionmanager
|
||||
$(package)_config_opts += -no-feature-sql
|
||||
$(package)_config_opts += -no-feature-statemachine
|
||||
$(package)_config_opts += -no-feature-syntaxhighlighter
|
||||
$(package)_config_opts += -no-feature-textbrowser
|
||||
$(package)_config_opts += -no-feature-textodfwriter
|
||||
$(package)_config_opts += -no-feature-topleveldomain
|
||||
$(package)_config_opts += -no-feature-udpsocket
|
||||
$(package)_config_opts += -no-feature-undocommand
|
||||
$(package)_config_opts += -no-feature-undogroup
|
||||
$(package)_config_opts += -no-feature-undostack
|
||||
$(package)_config_opts += -no-feature-undoview
|
||||
$(package)_config_opts += -no-feature-vnc
|
||||
$(package)_config_opts += -no-feature-wizard
|
||||
$(package)_config_opts_linux = -no-fontconfig
|
||||
$(package)_config_opts_linux += -no-opengl
|
||||
$(package)_config_opts_linux += -no-xcb
|
||||
$(package)_config_opts_linux += -no-feature-xlib
|
||||
$(package)_config_opts += -no-feature-printdialog
|
||||
$(package)_config_opts += -no-gui
|
||||
$(package)_config_opts += -no-freetype
|
||||
$(package)_config_opts += -no-sm
|
||||
$(package)_config_opts += -no-fontconfig
|
||||
$(package)_config_opts += -no-opengl
|
||||
$(package)_config_opts += -no-xkb
|
||||
$(package)_config_opts += -no-xcb
|
||||
$(package)_config_opts += -no-xshape
|
||||
$(package)_build_env = QT_RCC_TEST=1
|
||||
endef
|
||||
|
||||
define $(package)_fetch_cmds
|
||||
@@ -125,24 +108,14 @@ endef
|
||||
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
sed -i.old "s|FT_Get_Font_Format|FT_Get_X11_Font_Format|" qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp && \
|
||||
sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \
|
||||
sed -i.old "/updateqm.depends =/d" qttranslations/translations/translations.pro && \
|
||||
sed -i.old "s/src_plugins.depends = src_sql src_network/src_plugins.depends = src_network/" qtbase/src/src.pro && \
|
||||
cp -r qtbase/mkspecs/linux-arm-gnueabi-g++ qtbase/mkspecs/bitcoin-linux-g++ && \
|
||||
sed -i.old "s/arm-linux-gnueabi-/$(host)-/g" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \
|
||||
patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \
|
||||
patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \
|
||||
patch -p1 < $($(package)_patch_dir)/pidlist_absolute.patch && \
|
||||
patch -p1 < $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \
|
||||
patch -p1 < $($(package)_patch_dir)/qfixed-coretext.patch && \
|
||||
echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
|
||||
echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
|
||||
echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
|
||||
patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \
|
||||
echo "QMAKE_LINK_OBJECT_MAX = 10" >> qtbase/mkspecs/win32-g++/qmake.conf && \
|
||||
echo "QMAKE_LINK_OBJECT_SCRIPT = object_script" >> qtbase/mkspecs/win32-g++/qmake.conf && \
|
||||
sed -i.old "s|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
|
||||
sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
|
||||
sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \
|
||||
sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf
|
||||
echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
|
||||
24
contrib/depends/patches/openssl/fix_arflags.patch
Normal file
24
contrib/depends/patches/openssl/fix_arflags.patch
Normal file
@@ -0,0 +1,24 @@
|
||||
--- Makefile.org.O 2019-02-26 14:20:20.000000000 +0000
|
||||
+++ Makefile.org 2019-11-15 13:05:54.370086856 +0000
|
||||
@@ -63,8 +63,8 @@
|
||||
PEX_LIBS=
|
||||
EX_LIBS=
|
||||
EXE_EXT=
|
||||
-ARFLAGS=
|
||||
-AR=ar $(ARFLAGS) r
|
||||
+ARFLAGS= r
|
||||
+AR=ar $(ARFLAGS)
|
||||
RANLIB= ranlib
|
||||
RC= windres
|
||||
NM= nm
|
||||
--- Configure.O 2019-02-26 14:20:20.000000000 +0000
|
||||
+++ Configure 2019-11-16 07:43:14.933990774 +0000
|
||||
@@ -1251,7 +1251,7 @@
|
||||
my $shared_extension = $fields[$idx_shared_extension];
|
||||
my $ranlib = $ENV{'RANLIB'} || $fields[$idx_ranlib];
|
||||
my $ar = $ENV{'AR'} || "ar";
|
||||
-my $arflags = $fields[$idx_arflags];
|
||||
+my $arflags = $ENV{'ARFLAGS'} || $fields[$idx_arflags];
|
||||
my $windres = $ENV{'RC'} || $ENV{'WINDRES'} || "windres";
|
||||
my $multilib = $fields[$idx_multilib];
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
--- x/qtbase/src/plugins/platforms/cocoa/qprintengine_mac_p.h
|
||||
+++ y/qtbase/src/plugins/platforms/cocoa/qprintengine_mac_p.h
|
||||
@@ -52,6 +52,7 @@
|
||||
//
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
+#include <qpa/qplatformprintdevice.h>
|
||||
|
||||
#ifndef QT_NO_PRINTER
|
||||
|
||||
--- x/qtbase/src/plugins/plugins.pro
|
||||
+++ y/qtbase/src/plugins/plugins.pro
|
||||
@@ -9,6 +9,3 @@ qtHaveModule(gui) {
|
||||
!android:qtConfig(library): SUBDIRS *= generic
|
||||
}
|
||||
qtHaveModule(widgets): SUBDIRS += styles
|
||||
-
|
||||
-!winrt:qtHaveModule(printsupport): \
|
||||
- SUBDIRS += printsupport
|
||||
@@ -1,11 +1,11 @@
|
||||
--- old/qtbase/mkspecs/features/qt_module.prf
|
||||
+++ new/qtbase/mkspecs/features/qt_module.prf
|
||||
@@ -269,7 +269,7 @@ load(qt_installs)
|
||||
@@ -245,7 +245,7 @@
|
||||
load(qt_targets)
|
||||
|
||||
# this builds on top of qt_common
|
||||
-!internal_module:if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) {
|
||||
+if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) {
|
||||
-!internal_module:!lib_bundle:if(unix|mingw) {
|
||||
+unix|mingw {
|
||||
CONFIG += create_pc
|
||||
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
|
||||
host_build: \
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
--- old/qtbase/src/tools/rcc/rcc.cpp
|
||||
+++ new/qtbase/src/tools/rcc/rcc.cpp
|
||||
@@ -207,7 +207,11 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
|
||||
if (lib.formatVersion() >= 2) {
|
||||
// last modified time stamp
|
||||
const QDateTime lastModified = m_fileInfo.lastModified();
|
||||
- lib.writeNumber8(quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0));
|
||||
+ quint64 lastmod = quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0);
|
||||
+ static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong();
|
||||
+ if (sourceDate != 0)
|
||||
+ lastmod = sourceDate;
|
||||
+ lib.writeNumber8(lastmod);
|
||||
if (text || pass1)
|
||||
lib.writeChar('\n');
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
From 9563cef873ae82e06f60708d706d054717e801ce Mon Sep 17 00:00:00 2001
|
||||
From: Carl Dong <contact@carldong.me>
|
||||
Date: Thu, 18 Jul 2019 17:22:05 -0400
|
||||
Subject: [PATCH] Wrap xlib related code blocks in #if's
|
||||
|
||||
They are not necessary to compile QT.
|
||||
---
|
||||
qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp b/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp
|
||||
index 7c62c2e2b3..c05c6c0a07 100644
|
||||
--- a/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp
|
||||
+++ b/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp
|
||||
@@ -49,7 +49,9 @@
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QBitmap>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
|
||||
#include <X11/cursorfont.h>
|
||||
+#endif
|
||||
#include <xcb/xfixes.h>
|
||||
#include <xcb/xcb_image.h>
|
||||
|
||||
@@ -391,6 +393,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *window)
|
||||
xcb_flush(xcb_connection());
|
||||
}
|
||||
|
||||
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
|
||||
static int cursorIdForShape(int cshape)
|
||||
{
|
||||
int cursorId = 0;
|
||||
@@ -444,6 +447,7 @@ static int cursorIdForShape(int cshape)
|
||||
}
|
||||
return cursorId;
|
||||
}
|
||||
+#endif
|
||||
|
||||
xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
|
||||
{
|
||||
@@ -556,7 +560,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape)
|
||||
xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
|
||||
{
|
||||
xcb_connection_t *conn = xcb_connection();
|
||||
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
|
||||
int cursorId = cursorIdForShape(cshape);
|
||||
+#endif
|
||||
xcb_cursor_t cursor = XCB_NONE;
|
||||
|
||||
// Try Xcursor first
|
||||
@@ -586,6 +592,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
|
||||
// Non-standard X11 cursors are created from bitmaps
|
||||
cursor = createNonStandardCursor(cshape);
|
||||
|
||||
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
|
||||
// Create a glpyh cursor if everything else failed
|
||||
if (!cursor && cursorId) {
|
||||
cursor = xcb_generate_id(conn);
|
||||
@@ -593,6 +600,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
|
||||
cursorId, cursorId + 1,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0);
|
||||
}
|
||||
+#endif
|
||||
|
||||
if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) {
|
||||
const char *name = cursorNames[cshape].front();
|
||||
---
|
||||
2.22.0
|
||||
|
||||
37
contrib/depends/patches/qt/pidlist_absolute.patch
Normal file
37
contrib/depends/patches/qt/pidlist_absolute.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
diff -dur old/qtbase/src/plugins/platforms/windows/qwindowscontext.h new/qtbase/src/plugins/platforms/windows/qwindowscontext.h
|
||||
--- old/qtbase/src/plugins/platforms/windows/qwindowscontext.h
|
||||
+++ new/qtbase/src/plugins/platforms/windows/qwindowscontext.h
|
||||
@@ -136,10 +136,18 @@
|
||||
inline void init();
|
||||
|
||||
typedef HRESULT (WINAPI *SHCreateItemFromParsingName)(PCWSTR, IBindCtx *, const GUID&, void **);
|
||||
+#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3)
|
||||
+ typedef HRESULT (WINAPI *SHGetKnownFolderIDList)(const GUID &, DWORD, HANDLE, ITEMIDLIST **);
|
||||
+#else
|
||||
typedef HRESULT (WINAPI *SHGetKnownFolderIDList)(const GUID &, DWORD, HANDLE, PIDLIST_ABSOLUTE *);
|
||||
+#endif
|
||||
typedef HRESULT (WINAPI *SHGetStockIconInfo)(int , int , _SHSTOCKICONINFO *);
|
||||
typedef HRESULT (WINAPI *SHGetImageList)(int, REFIID , void **);
|
||||
+#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3)
|
||||
+ typedef HRESULT (WINAPI *SHCreateItemFromIDList)(const ITEMIDLIST *, REFIID, void **);
|
||||
+#else
|
||||
typedef HRESULT (WINAPI *SHCreateItemFromIDList)(PCIDLIST_ABSOLUTE, REFIID, void **);
|
||||
+#endif
|
||||
|
||||
SHCreateItemFromParsingName sHCreateItemFromParsingName;
|
||||
SHGetKnownFolderIDList sHGetKnownFolderIDList;
|
||||
diff -dur old/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp new/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
|
||||
--- old/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
|
||||
+++ new/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
|
||||
@@ -1016,7 +1016,11 @@
|
||||
qWarning() << __FUNCTION__ << ": Invalid CLSID: " << url.path();
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
+#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3)
|
||||
+ ITEMIDLIST *idList;
|
||||
+#else
|
||||
PIDLIST_ABSOLUTE idList;
|
||||
+#endif
|
||||
HRESULT hr = QWindowsContext::shell32dll.sHGetKnownFolderIDList(uuid, 0, 0, &idList);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning("%s: SHGetKnownFolderIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString()));
|
||||
34
contrib/depends/patches/qt/qfixed-coretext.patch
Normal file
34
contrib/depends/patches/qt/qfixed-coretext.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
From dbdd5f0ffbce52c8b789ed09f1aa3f1da6c02e23 Mon Sep 17 00:00:00 2001
|
||||
From: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
|
||||
Date: Fri, 30 Mar 2018 11:58:16 -0700
|
||||
Subject: [PATCH] QCoreTextFontEngine: Fix build with Xcode 9.3
|
||||
|
||||
Apple LLVM version 9.1.0 (clang-902.0.39.1)
|
||||
|
||||
Error message:
|
||||
|
||||
.../qfontengine_coretext.mm:827:20: error: qualified reference to
|
||||
'QFixed' is a constructor name rather than a type in this context
|
||||
return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
|
||||
Change-Id: Iebe26b3b087a16b10664208fc8851cbddb47f043
|
||||
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
|
||||
---
|
||||
src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git old/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm new/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
index 25ff69d877d..98b753eff96 100644
|
||||
--- old/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
+++ new/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
@@ -824,7 +824,7 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, gl
|
||||
|
||||
QFixed QCoreTextFontEngine::emSquareSize() const
|
||||
{
|
||||
- return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
+ return QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
}
|
||||
|
||||
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
|
||||
--
|
||||
2.16.3
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
#set(Boost_DEBUG 1)
|
||||
find_package(Boost COMPONENTS system filesystem thread date_time chrono regex )
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace epee
|
||||
explicit byte_slice(std::string&& buffer);
|
||||
|
||||
//! Convert `stream` into a slice with zero allocations.
|
||||
explicit byte_slice(byte_stream&& stream, bool shrink = true);
|
||||
explicit byte_slice(byte_stream&& stream) noexcept;
|
||||
|
||||
byte_slice(byte_slice&& source) noexcept;
|
||||
~byte_slice() noexcept = default;
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace epee
|
||||
byte_buffer buffer_; //! Beginning of buffer
|
||||
std::uint8_t* next_write_; //! Current write position
|
||||
const std::uint8_t* end_; //! End of buffer
|
||||
std::size_t increase_size_; //! Minimum buffer size increase
|
||||
|
||||
//! \post `requested <= available()`
|
||||
void overflow(const std::size_t requested);
|
||||
@@ -74,17 +75,29 @@ namespace epee
|
||||
using char_type = std::uint8_t;
|
||||
using Ch = char_type;
|
||||
|
||||
//! \return Default minimum size increase on buffer overflow
|
||||
static constexpr std::size_t default_increase() noexcept { return 4096; }
|
||||
|
||||
//! Increase internal buffer by at least `byte_stream_increase` bytes.
|
||||
byte_stream() noexcept
|
||||
: byte_stream(default_increase())
|
||||
{}
|
||||
|
||||
//! Increase internal buffer by at least `increase` bytes.
|
||||
explicit byte_stream(const std::size_t increase) noexcept
|
||||
: buffer_(nullptr),
|
||||
next_write_(nullptr),
|
||||
end_(nullptr)
|
||||
end_(nullptr),
|
||||
increase_size_(increase)
|
||||
{}
|
||||
|
||||
byte_stream(byte_stream&& rhs) noexcept;
|
||||
~byte_stream() noexcept = default;
|
||||
byte_stream& operator=(byte_stream&& rhs) noexcept;
|
||||
|
||||
//! \return The minimum increase size on buffer overflow
|
||||
std::size_t increase_size() const noexcept { return increase_size_; }
|
||||
|
||||
const std::uint8_t* data() const noexcept { return buffer_.get(); }
|
||||
std::uint8_t* tellp() const noexcept { return next_write_; }
|
||||
std::size_t available() const noexcept { return end_ - next_write_; }
|
||||
@@ -175,7 +188,7 @@ namespace epee
|
||||
void put_n(const std::uint8_t ch, const std::size_t count)
|
||||
{
|
||||
check(count);
|
||||
std::memset(tellp(), ch, count);
|
||||
std::memset(tellp(), count, ch);
|
||||
next_write_ += count;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,23 +24,211 @@
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
|
||||
#ifndef _FILE_IO_UTILS_H_
|
||||
#define _FILE_IO_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include "string_tools.h"
|
||||
#endif
|
||||
|
||||
// On Windows there is a problem with non-ASCII characters in path and file names
|
||||
// as far as support by the standard components used is concerned:
|
||||
|
||||
// The various file stream classes, e.g. std::ifstream and std::ofstream, are
|
||||
// part of the GNU C++ Library / libstdc++. On the most basic level they use the
|
||||
// fopen() call as defined / made accessible to programs compiled within MSYS2
|
||||
// by the stdio.h header file maintained by the MinGW project.
|
||||
|
||||
// The critical point: The implementation of fopen() is part of MSVCRT, the
|
||||
// Microsoft Visual C/C++ Runtime Library, and this method does NOT offer any
|
||||
// Unicode support.
|
||||
|
||||
// Monero code that would want to continue to use the normal file stream classes
|
||||
// but WITH Unicode support could therefore not solve this problem on its own,
|
||||
// but 2 different projects from 2 different maintaining groups would need changes
|
||||
// in this particular direction - something probably difficult to achieve and
|
||||
// with a long time to wait until all new versions / releases arrive.
|
||||
|
||||
// Implemented solution approach: Circumvent the problem by stopping to use std
|
||||
// file stream classes on Windows and directly use Unicode-capable WIN32 API
|
||||
// calls. Most of the code doing so is concentrated in this header file here.
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace file_io_utils
|
||||
{
|
||||
bool is_file_exist(const std::string& path);
|
||||
bool save_string_to_file(const std::string& path_to_file, const std::string& str);
|
||||
bool get_file_time(const std::string& path_to_file, time_t& ft);
|
||||
bool set_file_time(const std::string& path_to_file, const time_t& ft);
|
||||
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000);
|
||||
bool append_string_to_file(const std::string& path_to_file, const std::string& str);
|
||||
bool get_file_size(const std::string& path_to_file, uint64_t &size);
|
||||
inline
|
||||
bool is_file_exist(const std::string& path)
|
||||
{
|
||||
boost::filesystem::path p(path);
|
||||
return boost::filesystem::exists(p);
|
||||
}
|
||||
|
||||
inline
|
||||
bool save_string_to_file(const std::string& path_to_file, const std::string& str)
|
||||
{
|
||||
#ifdef WIN32
|
||||
std::wstring wide_path;
|
||||
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
|
||||
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
DWORD bytes_written;
|
||||
DWORD bytes_to_write = (DWORD)str.size();
|
||||
BOOL result = WriteFile(file_handle, str.data(), bytes_to_write, &bytes_written, NULL);
|
||||
CloseHandle(file_handle);
|
||||
if (bytes_written != bytes_to_write)
|
||||
result = FALSE;
|
||||
return result;
|
||||
#else
|
||||
try
|
||||
{
|
||||
std::ofstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
|
||||
fstream << str;
|
||||
fstream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
bool get_file_time(const std::string& path_to_file, time_t& ft)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec);
|
||||
if(!ec)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
inline
|
||||
bool set_file_time(const std::string& path_to_file, const time_t& ft)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec);
|
||||
if(!ec)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000)
|
||||
{
|
||||
#ifdef WIN32
|
||||
std::wstring wide_path;
|
||||
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
|
||||
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
DWORD file_size = GetFileSize(file_handle, NULL);
|
||||
if ((file_size == INVALID_FILE_SIZE) || (uint64_t)file_size > (uint64_t)max_size) {
|
||||
CloseHandle(file_handle);
|
||||
return false;
|
||||
}
|
||||
target_str.resize(file_size);
|
||||
DWORD bytes_read;
|
||||
BOOL result = ReadFile(file_handle, &target_str[0], file_size, &bytes_read, NULL);
|
||||
CloseHandle(file_handle);
|
||||
if (bytes_read != file_size)
|
||||
result = FALSE;
|
||||
return result;
|
||||
#else
|
||||
try
|
||||
{
|
||||
std::ifstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
|
||||
|
||||
std::ifstream::pos_type file_size = fstream.tellg();
|
||||
|
||||
if((uint64_t)file_size > (uint64_t)max_size) // ensure a large domain for comparison, and negative -> too large
|
||||
return false;//don't go crazy
|
||||
size_t file_size_t = static_cast<size_t>(file_size);
|
||||
|
||||
target_str.resize(file_size_t);
|
||||
|
||||
fstream.seekg (0, std::ios::beg);
|
||||
fstream.read((char*)target_str.data(), target_str.size());
|
||||
fstream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
bool append_string_to_file(const std::string& path_to_file, const std::string& str)
|
||||
{
|
||||
// No special Windows implementation because so far not used in Monero code
|
||||
try
|
||||
{
|
||||
std::ofstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
|
||||
fstream << str;
|
||||
fstream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
bool get_file_size(const std::string& path_to_file, uint64_t &size)
|
||||
{
|
||||
#ifdef WIN32
|
||||
std::wstring wide_path;
|
||||
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
|
||||
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
LARGE_INTEGER file_size;
|
||||
BOOL result = GetFileSizeEx(file_handle, &file_size);
|
||||
CloseHandle(file_handle);
|
||||
if (result) {
|
||||
size = file_size.QuadPart;
|
||||
}
|
||||
return size;
|
||||
#else
|
||||
try
|
||||
{
|
||||
std::ifstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
|
||||
size = fstream.tellg();
|
||||
fstream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -28,11 +28,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <limits>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/utility/value_init.hpp>
|
||||
namespace epee
|
||||
{
|
||||
#define STD_TRY_BEGIN() try {
|
||||
@@ -97,7 +95,16 @@ namespace misc_utils
|
||||
return memcmp(&_Left, &_Right, sizeof(_Left)) < 0;
|
||||
}
|
||||
|
||||
bool sleep_no_w(long ms );
|
||||
|
||||
inline
|
||||
bool sleep_no_w(long ms )
|
||||
{
|
||||
boost::this_thread::sleep(
|
||||
boost::get_system_time() +
|
||||
boost::posix_time::milliseconds( std::max<long>(ms,0) ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_mid(const T &a, const T &b)
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#define MAX_LOG_FILES 50
|
||||
|
||||
#define MCLOG_TYPE(level, cat, color, type, x) do { \
|
||||
if (el::Loggers::allowed(level, cat)) { \
|
||||
if (ELPP->vRegistry()->allowed(level, cat)) { \
|
||||
el::base::Writer(level, color, __FILE__, __LINE__, ELPP_FUNC, type).construct(cat) << x; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -89,7 +89,7 @@
|
||||
|
||||
#define IFLOG(level, cat, color, type, init, x) \
|
||||
do { \
|
||||
if (el::Loggers::allowed(level, cat)) { \
|
||||
if (ELPP->vRegistry()->allowed(level, cat)) { \
|
||||
init; \
|
||||
el::base::Writer(level, color, __FILE__, __LINE__, ELPP_FUNC, type).construct(cat) << x; \
|
||||
} \
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#pragma once
|
||||
namespace epee
|
||||
@@ -115,7 +115,15 @@ namespace misc_utils
|
||||
|
||||
}
|
||||
|
||||
std::string get_thread_string_id();
|
||||
|
||||
inline std::string get_thread_string_id()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return boost::lexical_cast<std::string>(GetCurrentThreadId());
|
||||
#elif defined(__GNUC__)
|
||||
return boost::lexical_cast<std::string>(pthread_self());
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool get_gmt_time(time_t t, struct tm &tm)
|
||||
{
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace http
|
||||
virtual bool connect(std::chrono::milliseconds timeout) = 0;
|
||||
virtual bool disconnect() = 0;
|
||||
virtual bool is_connected(bool *ssl = NULL) = 0;
|
||||
virtual bool invoke(const boost::string_ref uri, const boost::string_ref method, const boost::string_ref body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual bool invoke(const boost::string_ref uri, const boost::string_ref method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual bool invoke_get(const boost::string_ref uri, std::chrono::milliseconds timeout, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual bool invoke_post(const boost::string_ref uri, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual uint64_t get_bytes_sent() const = 0;
|
||||
|
||||
@@ -265,12 +265,6 @@ namespace net_utils
|
||||
template<class t_callback>
|
||||
bool connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeot, const t_callback &cb, const std::string& bind_ip = "0.0.0.0", epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect);
|
||||
|
||||
boost::asio::ssl::context& get_ssl_context() noexcept
|
||||
{
|
||||
assert(m_state != nullptr);
|
||||
return m_state->ssl_context;
|
||||
}
|
||||
|
||||
typename t_protocol_handler::config_type& get_config_object()
|
||||
{
|
||||
assert(m_state != nullptr); // always set in constructor
|
||||
|
||||
@@ -40,9 +40,8 @@
|
||||
#include <boost/date_time/posix_time/posix_time.hpp> // TODO
|
||||
#include <boost/thread/condition_variable.hpp> // TODO
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include "warnings.h"
|
||||
#include "string_tools_lexical.h"
|
||||
#include "string_tools.h"
|
||||
#include "misc_language.h"
|
||||
#include "net/local_ip.h"
|
||||
#include "pragma_comp_defs.h"
|
||||
@@ -208,6 +207,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
buffer_ssl_init_fill = 0;
|
||||
if (is_income && m_ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_disabled)
|
||||
socket().async_receive(boost::asio::buffer(buffer_),
|
||||
boost::asio::socket_base::message_peek,
|
||||
strand_.wrap(
|
||||
std::bind(&connection<t_protocol_handler>::handle_receive, self,
|
||||
std::placeholders::_1,
|
||||
@@ -270,6 +270,8 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
//_dbg3("[sock " << socket().native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number);
|
||||
CRITICAL_REGION_LOCAL(self->m_self_refs_lock);
|
||||
//_dbg3("[sock " << socket().native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number);
|
||||
if(m_was_shutdown)
|
||||
return false;
|
||||
++m_reference_count;
|
||||
m_self_ref = std::move(self);
|
||||
return true;
|
||||
@@ -332,9 +334,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
TRY_ENTRY();
|
||||
//_info("[sock " << socket().native_handle() << "] Async read calledback.");
|
||||
|
||||
if (m_was_shutdown)
|
||||
return;
|
||||
|
||||
if (!e)
|
||||
{
|
||||
double current_speed_down;
|
||||
@@ -361,9 +360,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
CRITICAL_REGION_LOCAL( epee::net_utils::network_throttle_manager::m_lock_get_global_throttle_in );
|
||||
delay = epee::net_utils::network_throttle_manager::get_global_throttle_in().get_sleep_time_after_tick( bytes_transferred );
|
||||
}
|
||||
|
||||
if (m_was_shutdown)
|
||||
return;
|
||||
|
||||
delay *= 0.5;
|
||||
long int ms = (long int)(delay * 100);
|
||||
@@ -435,9 +431,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
||||
if (m_was_shutdown) return;
|
||||
|
||||
if (e)
|
||||
{
|
||||
// offload the error case
|
||||
@@ -445,11 +438,13 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
return;
|
||||
}
|
||||
|
||||
reset_timer(get_timeout_from_bytes_read(bytes_transferred), false);
|
||||
|
||||
buffer_ssl_init_fill += bytes_transferred;
|
||||
MTRACE("we now have " << buffer_ssl_init_fill << "/" << get_ssl_magic_size() << " bytes needed to detect SSL");
|
||||
if (buffer_ssl_init_fill < get_ssl_magic_size())
|
||||
if (buffer_ssl_init_fill <= get_ssl_magic_size())
|
||||
{
|
||||
socket().async_receive(boost::asio::buffer(buffer_.data() + buffer_ssl_init_fill, buffer_.size() - buffer_ssl_init_fill),
|
||||
boost::asio::socket_base::message_peek,
|
||||
strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_receive, connection<t_protocol_handler>::shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
@@ -475,7 +470,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled)
|
||||
{
|
||||
// Handshake
|
||||
if (!handshake(boost::asio::ssl::stream_base::server, boost::asio::const_buffer(buffer_.data(), buffer_ssl_init_fill)))
|
||||
if (!handshake(boost::asio::ssl::stream_base::server))
|
||||
{
|
||||
MERROR("SSL handshake failed");
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_want_close_connection, 1);
|
||||
@@ -490,11 +485,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_read(e, buffer_ssl_init_fill);
|
||||
return;
|
||||
}
|
||||
|
||||
async_read_some(boost::asio::buffer(buffer_),
|
||||
strand_.wrap(
|
||||
@@ -561,7 +551,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
{ // LOCK: chunking
|
||||
epee::critical_region_t<decltype(m_chunking_lock)> send_guard(m_chunking_lock); // *** critical ***
|
||||
|
||||
MDEBUG("do_send() will SPLIT into small chunks, from packet="<<message_size<<" B for ptr="<<(const void*)message_data);
|
||||
MDEBUG("do_send() will SPLIT into small chunks, from packet="<<message_size<<" B for ptr="<<message_data);
|
||||
// 01234567890
|
||||
// ^^^^ (pos=0, len=4) ; pos:=pos+len, pos=4
|
||||
// ^^^^ (pos=4, len=4) ; pos:=pos+len, pos=8
|
||||
@@ -574,14 +564,14 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
while (!message.empty()) {
|
||||
byte_slice chunk = message.take_slice(chunksize_good);
|
||||
|
||||
MDEBUG("chunk_start="<<(void*)chunk.data()<<" ptr="<<(const void*)message_data<<" pos="<<(chunk.data() - message_data));
|
||||
MDEBUG("chunk_start="<<(void*)chunk.data()<<" ptr="<<message_data<<" pos="<<(chunk.data() - message_data));
|
||||
MDEBUG("part of " << message.size() << ": pos="<<(chunk.data() - message_data) << " len="<<chunk.size());
|
||||
|
||||
bool ok = do_send_chunk(std::move(chunk)); // <====== ***
|
||||
|
||||
all_ok = all_ok && ok;
|
||||
if (!all_ok) {
|
||||
MDEBUG("do_send() DONE ***FAILED*** from packet="<<message_size<<" B for ptr="<<(const void*)message_data);
|
||||
MDEBUG("do_send() DONE ***FAILED*** from packet="<<message_size<<" B for ptr="<<message_data);
|
||||
MDEBUG("do_send() SEND was aborted in middle of big package - this is mostly harmless "
|
||||
<< " (e.g. peer closed connection) but if it causes trouble tell us at #monero-dev. " << message_size);
|
||||
return false; // partial failure in sending
|
||||
@@ -589,7 +579,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
// (in catch block, or uniq pointer) delete buf;
|
||||
} // each chunk
|
||||
|
||||
MDEBUG("do_send() DONE SPLIT from packet="<<message_size<<" B for ptr="<<(const void*)message_data);
|
||||
MDEBUG("do_send() DONE SPLIT from packet="<<message_size<<" B for ptr="<<message_data);
|
||||
|
||||
MDEBUG("do_send() m_connection_type = " << m_connection_type);
|
||||
|
||||
@@ -661,8 +651,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds( ms ) );
|
||||
m_send_que_lock.lock();
|
||||
_dbg1("sleep for queue: " << ms);
|
||||
if (m_was_shutdown)
|
||||
return false;
|
||||
|
||||
if (retry > retry_limit) {
|
||||
MWARNING("send que size is more than ABSTRACT_SERVER_SEND_QUE_MAX_COUNT(" << ABSTRACT_SERVER_SEND_QUE_MAX_COUNT << "), shutting down connection");
|
||||
@@ -760,8 +748,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
template<class t_protocol_handler>
|
||||
void connection<t_protocol_handler>::reset_timer(boost::posix_time::milliseconds ms, bool add)
|
||||
{
|
||||
const auto tms = ms.total_milliseconds();
|
||||
if (tms < 0 || (add && tms == 0))
|
||||
if (ms.total_milliseconds() < 0)
|
||||
{
|
||||
MWARNING("Ignoring negative timeout " << ms);
|
||||
return;
|
||||
|
||||
@@ -132,10 +132,10 @@ class connection_basic { // not-templated base class for rapid developmet of som
|
||||
ssl_support_t get_ssl_support() const { return m_ssl_support; }
|
||||
void disable_ssl() { m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; }
|
||||
|
||||
bool handshake(boost::asio::ssl::stream_base::handshake_type type, boost::asio::const_buffer buffer = {})
|
||||
bool handshake(boost::asio::ssl::stream_base::handshake_type type)
|
||||
{
|
||||
//m_state != nullptr verified in constructor
|
||||
return m_state->ssl_options().handshake(socket_, type, buffer);
|
||||
return m_state->ssl_options().handshake(socket_, type);
|
||||
}
|
||||
|
||||
template<typename MutableBufferSequence, typename ReadHandler>
|
||||
|
||||
@@ -27,13 +27,14 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "memwipe.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <list>
|
||||
|
||||
#include "memwipe.h"
|
||||
#include "string_tools.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
|
||||
@@ -65,9 +66,34 @@ namespace net_utils
|
||||
|
||||
typedef std::list<std::pair<std::string, std::string> > fields_list;
|
||||
|
||||
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields);
|
||||
inline
|
||||
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields)
|
||||
{
|
||||
fields_list::const_iterator it = fields.begin();
|
||||
for(; it != fields.end(); it++)
|
||||
if(!string_tools::compare_no_case(param_name, it->first))
|
||||
break;
|
||||
|
||||
std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri);
|
||||
if(it==fields.end())
|
||||
return std::string();
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri)
|
||||
{
|
||||
std::string buff = "([\\?|&])";
|
||||
buff += param_name + "=([^&]*)";
|
||||
boost::regex match_param(buff.c_str(), boost::regex::icase | boost::regex::normal);
|
||||
boost::smatch result;
|
||||
if(boost::regex_search(uri, result, match_param, boost::match_default) && result[0].matched)
|
||||
{
|
||||
return result[2];
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static inline void add_field(std::string& out, const boost::string_ref name, const boost::string_ref value)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <ctype.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
//#include <mbstring.h>
|
||||
@@ -45,7 +46,6 @@
|
||||
#endif
|
||||
|
||||
#include "string_tools.h"
|
||||
#include "string_tools_lexical.h"
|
||||
#include "reg_exp_definer.h"
|
||||
#include "abstract_http_client.h"
|
||||
#include "http_base.h"
|
||||
@@ -233,7 +233,7 @@ namespace net_utils
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
inline bool invoke(const boost::string_ref uri, const boost::string_ref method, const boost::string_ref body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) override
|
||||
inline bool invoke(const boost::string_ref uri, const boost::string_ref method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) override
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
if(!is_connected())
|
||||
|
||||
@@ -74,13 +74,7 @@
|
||||
uint64_t ticks = misc_utils::get_tick_count(); \
|
||||
boost::value_initialized<command_type::request> req; \
|
||||
bool parse_res = epee::serialization::load_t_from_json(static_cast<command_type::request&>(req), query_info.m_body); \
|
||||
if (!parse_res) \
|
||||
{ \
|
||||
MERROR("Failed to parse json: \r\n" << query_info.m_body); \
|
||||
response_info.m_response_code = 400; \
|
||||
response_info.m_response_comment = "Bad request"; \
|
||||
return true; \
|
||||
} \
|
||||
CHECK_AND_ASSERT_MES(parse_res, false, "Failed to parse json: \r\n" << query_info.m_body); \
|
||||
uint64_t ticks1 = epee::misc_utils::get_tick_count(); \
|
||||
boost::value_initialized<command_type::response> resp;\
|
||||
MINFO(m_conn_context << "calling " << s_pattern); \
|
||||
@@ -110,13 +104,7 @@
|
||||
uint64_t ticks = misc_utils::get_tick_count(); \
|
||||
boost::value_initialized<command_type::request> req; \
|
||||
bool parse_res = epee::serialization::load_t_from_binary(static_cast<command_type::request&>(req), epee::strspan<uint8_t>(query_info.m_body)); \
|
||||
if (!parse_res) \
|
||||
{ \
|
||||
MERROR("Failed to parse bin body data, body size=" << query_info.m_body.size()); \
|
||||
response_info.m_response_code = 400; \
|
||||
response_info.m_response_comment = "Bad request"; \
|
||||
return true; \
|
||||
} \
|
||||
CHECK_AND_ASSERT_MES(parse_res, false, "Failed to parse bin body data, body size=" << query_info.m_body.size()); \
|
||||
uint64_t ticks1 = misc_utils::get_tick_count(); \
|
||||
boost::value_initialized<command_type::response> resp;\
|
||||
MINFO(m_conn_context << "calling " << s_pattern); \
|
||||
@@ -130,10 +118,8 @@
|
||||
return true; \
|
||||
} \
|
||||
uint64_t ticks2 = misc_utils::get_tick_count(); \
|
||||
epee::byte_slice buffer; \
|
||||
epee::serialization::store_t_to_binary(static_cast<command_type::response&>(resp), buffer, 64 * 1024); \
|
||||
epee::serialization::store_t_to_binary(static_cast<command_type::response&>(resp), response_info.m_body); \
|
||||
uint64_t ticks3 = epee::misc_utils::get_tick_count(); \
|
||||
response_info.m_body.assign(reinterpret_cast<const char*>(buffer.data()), buffer.size()); \
|
||||
response_info.m_mime_tipe = " application/octet-stream"; \
|
||||
response_info.m_header_info.m_content_type = " application/octet-stream"; \
|
||||
MDEBUG( s_pattern << "() processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms"); \
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "byte_stream.h"
|
||||
#include "byte_slice.h"
|
||||
#include "net_utils_base.h"
|
||||
#include "span.h"
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
namespace epee
|
||||
{
|
||||
class byte_slice;
|
||||
namespace levin
|
||||
{
|
||||
#pragma pack(push)
|
||||
@@ -73,8 +72,7 @@ namespace levin
|
||||
|
||||
|
||||
#define LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED 0
|
||||
#define LEVIN_INITIAL_MAX_PACKET_SIZE 256*1024 // 256 KiB before handshake
|
||||
#define LEVIN_DEFAULT_MAX_PACKET_SIZE 100000000 //100MB by default after handshake
|
||||
#define LEVIN_DEFAULT_MAX_PACKET_SIZE 100000000 //100MB by default
|
||||
|
||||
#define LEVIN_PACKET_REQUEST 0x00000001
|
||||
#define LEVIN_PACKET_RESPONSE 0x00000002
|
||||
@@ -84,12 +82,11 @@ namespace levin
|
||||
|
||||
#define LEVIN_PROTOCOL_VER_0 0
|
||||
#define LEVIN_PROTOCOL_VER_1 1
|
||||
|
||||
|
||||
template<class t_connection_context = net_utils::connection_context_base>
|
||||
struct levin_commands_handler
|
||||
{
|
||||
virtual int invoke(int command, const epee::span<const uint8_t> in_buff, byte_stream& buff_out, t_connection_context& context)=0;
|
||||
virtual int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, t_connection_context& context)=0;
|
||||
virtual int notify(int command, const epee::span<const uint8_t> in_buff, t_connection_context& context)=0;
|
||||
virtual void callback(t_connection_context& context){};
|
||||
|
||||
@@ -127,41 +124,12 @@ namespace levin
|
||||
}
|
||||
}
|
||||
|
||||
//! Provides space for levin (p2p) header, so that payload can be sent without copy
|
||||
class message_writer
|
||||
{
|
||||
byte_slice finalize(uint32_t command, uint32_t flags, uint32_t return_code, bool expect_response);
|
||||
public:
|
||||
using header = bucket_head2;
|
||||
|
||||
explicit message_writer(std::size_t reserve = 8192);
|
||||
|
||||
message_writer(const message_writer&) = delete;
|
||||
message_writer(message_writer&&) = default;
|
||||
~message_writer() = default;
|
||||
message_writer& operator=(const message_writer&) = delete;
|
||||
message_writer& operator=(message_writer&&) = default;
|
||||
|
||||
//! \return Size of payload (excludes header size).
|
||||
std::size_t payload_size() const noexcept
|
||||
{
|
||||
return buffer.size() < sizeof(header) ? 0 : buffer.size() - sizeof(header);
|
||||
}
|
||||
|
||||
byte_slice finalize_invoke(uint32_t command) { return finalize(command, LEVIN_PACKET_REQUEST, 0, true); }
|
||||
byte_slice finalize_notify(uint32_t command) { return finalize(command, LEVIN_PACKET_REQUEST, 0, false); }
|
||||
byte_slice finalize_response(uint32_t command, uint32_t return_code)
|
||||
{
|
||||
return finalize(command, LEVIN_PACKET_RESPONSE, return_code, false);
|
||||
}
|
||||
|
||||
//! Has space for levin header until a finalize method is used
|
||||
byte_stream buffer;
|
||||
};
|
||||
|
||||
//! \return Intialized levin header.
|
||||
bucket_head2 make_header(uint32_t command, uint64_t msg_size, uint32_t flags, bool expect_response) noexcept;
|
||||
|
||||
//! \return A levin notification message.
|
||||
byte_slice make_notify(int command, epee::span<const std::uint8_t> payload);
|
||||
|
||||
/*! Generate a dummy levin message.
|
||||
|
||||
\param noise_bytes Total size of the returned `byte_slice`.
|
||||
@@ -171,11 +139,12 @@ namespace levin
|
||||
|
||||
/*! Generate 1+ levin messages that are identical to the noise message size.
|
||||
|
||||
\param noise_size Each levin message will be identical to this value.
|
||||
\param noise Each levin message will be identical to the size of this
|
||||
message. The bytes from this message will be used for padding.
|
||||
\return `nullptr` if `noise.size()` is less than the levin header size.
|
||||
Otherwise, a levin notification message OR 2+ levin fragment messages.
|
||||
Each message is `noise.size()` in length. */
|
||||
byte_slice make_fragmented_notify(const std::size_t noise_size, int command, message_writer message);
|
||||
byte_slice make_fragmented_notify(const byte_slice& noise, int command, epee::span<const std::uint8_t> payload);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,21 +51,6 @@
|
||||
#define MIN_BYTES_WANTED 512
|
||||
#endif
|
||||
|
||||
template<typename context_t>
|
||||
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, const char* category)
|
||||
{
|
||||
MCINFO("net.p2p.traffic", context << bytes << " bytes " << (sent ? "sent" : "received") << (error ? "/corrupt" : "")
|
||||
<< " for category " << category << " initiated by " << (initiator ? "us" : "peer"));
|
||||
}
|
||||
|
||||
template<typename context_t>
|
||||
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, int command)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "command-%u", command);
|
||||
on_levin_traffic(context, initiator, sent, error, bytes, buf);
|
||||
}
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace levin
|
||||
@@ -99,14 +84,14 @@ class async_protocol_handler_config
|
||||
|
||||
public:
|
||||
typedef t_connection_context connection_context;
|
||||
uint64_t m_initial_max_packet_size;
|
||||
uint64_t m_max_packet_size;
|
||||
uint64_t m_max_packet_size;
|
||||
uint64_t m_invoke_timeout;
|
||||
|
||||
int invoke(int command, message_writer in_msg, std::string& buff_out, boost::uuids::uuid connection_id);
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, boost::uuids::uuid connection_id);
|
||||
template<class callback_t>
|
||||
int invoke_async(int command, message_writer in_msg, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED);
|
||||
int invoke_async(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED);
|
||||
|
||||
int notify(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id);
|
||||
int send(epee::byte_slice message, const boost::uuids::uuid& connection_id);
|
||||
bool close(boost::uuids::uuid connection_id);
|
||||
bool update_connection_context(const t_connection_context& contxt);
|
||||
@@ -120,7 +105,7 @@ public:
|
||||
size_t get_in_connections_count();
|
||||
void set_handler(levin_commands_handler<t_connection_context>* handler, void (*destroy)(levin_commands_handler<t_connection_context>*) = NULL);
|
||||
|
||||
async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_initial_max_packet_size(LEVIN_INITIAL_MAX_PACKET_SIZE), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE), m_invoke_timeout(LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
|
||||
async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE), m_invoke_timeout(LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
|
||||
{}
|
||||
~async_protocol_handler_config() { set_handler(NULL, NULL); }
|
||||
void del_out_connections(size_t count);
|
||||
@@ -136,17 +121,12 @@ class async_protocol_handler
|
||||
{
|
||||
std::string m_fragment_buffer;
|
||||
|
||||
bool send_message(byte_slice message)
|
||||
bool send_message(uint32_t command, epee::span<const uint8_t> in_buff, uint32_t flags, bool expect_response)
|
||||
{
|
||||
if (message.size() < sizeof(message_writer::header))
|
||||
const bucket_head2 head = make_header(command, in_buff.size(), flags, expect_response);
|
||||
if(!m_pservice_endpoint->do_send(byte_slice{as_byte_span(head), in_buff}))
|
||||
return false;
|
||||
|
||||
message_writer::header head;
|
||||
std::memcpy(std::addressof(head), message.data(), sizeof(head));
|
||||
if(!m_pservice_endpoint->do_send(std::move(message)))
|
||||
return false;
|
||||
|
||||
on_levin_traffic(m_connection_context, true, true, false, head.m_cb, head.m_command);
|
||||
MDEBUG(m_connection_context << "LEVIN_PACKET_SENT. [len=" << head.m_cb
|
||||
<< ", flags" << head.m_flags
|
||||
<< ", r?=" << head.m_have_to_return_data
|
||||
@@ -165,6 +145,7 @@ public:
|
||||
stream_state_body
|
||||
};
|
||||
|
||||
std::atomic<bool> m_deletion_initiated;
|
||||
std::atomic<bool> m_protocol_released;
|
||||
volatile uint32_t m_invoke_buf_ready;
|
||||
|
||||
@@ -181,7 +162,6 @@ public:
|
||||
net_utils::i_service_endpoint* m_pservice_endpoint;
|
||||
config_type& m_config;
|
||||
t_connection_context& m_connection_context;
|
||||
std::atomic<uint64_t> m_max_packet_size;
|
||||
|
||||
net_utils::buffer m_cache_in_buffer;
|
||||
stream_state m_state;
|
||||
@@ -309,12 +289,12 @@ public:
|
||||
m_current_head(bucket_head2()),
|
||||
m_pservice_endpoint(psnd_hndlr),
|
||||
m_config(config),
|
||||
m_connection_context(conn_context),
|
||||
m_max_packet_size(config.m_initial_max_packet_size),
|
||||
m_connection_context(conn_context),
|
||||
m_cache_in_buffer(4 * 1024),
|
||||
m_state(stream_state_head)
|
||||
{
|
||||
m_close_called = 0;
|
||||
m_deletion_initiated = false;
|
||||
m_protocol_released = false;
|
||||
m_wait_count = 0;
|
||||
m_oponent_protocol_ver = 0;
|
||||
@@ -327,6 +307,7 @@ public:
|
||||
try
|
||||
{
|
||||
|
||||
m_deletion_initiated = true;
|
||||
if(m_connection_initialized)
|
||||
{
|
||||
m_config.del_connection(this);
|
||||
@@ -418,14 +399,13 @@ public:
|
||||
}
|
||||
|
||||
// these should never fail, but do runtime check for safety
|
||||
const uint64_t max_packet_size = m_max_packet_size;
|
||||
CHECK_AND_ASSERT_MES(max_packet_size >= m_cache_in_buffer.size(), false, "Bad m_cache_in_buffer.size()");
|
||||
CHECK_AND_ASSERT_MES(max_packet_size - m_cache_in_buffer.size() >= m_fragment_buffer.size(), false, "Bad m_cache_in_buffer.size() + m_fragment_buffer.size()");
|
||||
CHECK_AND_ASSERT_MES(m_config.m_max_packet_size >= m_cache_in_buffer.size(), false, "Bad m_cache_in_buffer.size()");
|
||||
CHECK_AND_ASSERT_MES(m_config.m_max_packet_size - m_cache_in_buffer.size() >= m_fragment_buffer.size(), false, "Bad m_cache_in_buffer.size() + m_fragment_buffer.size()");
|
||||
|
||||
// flipped to subtraction; prevent overflow since m_max_packet_size is variable and public
|
||||
if(cb > max_packet_size - m_cache_in_buffer.size() - m_fragment_buffer.size())
|
||||
if(cb > m_config.m_max_packet_size - m_cache_in_buffer.size() - m_fragment_buffer.size())
|
||||
{
|
||||
MWARNING(m_connection_context << "Maximum packet size exceed!, m_max_packet_size = " << max_packet_size
|
||||
MWARNING(m_connection_context << "Maximum packet size exceed!, m_max_packet_size = " << m_config.m_max_packet_size
|
||||
<< ", packet received " << m_cache_in_buffer.size() + cb
|
||||
<< ", connection will be closed.");
|
||||
return false;
|
||||
@@ -450,7 +430,7 @@ public:
|
||||
//async call scenario
|
||||
boost::shared_ptr<invoke_response_handler_base> response_handler = m_invoke_response_handlers.front();
|
||||
response_handler->reset_timer();
|
||||
MDEBUG(m_connection_context << "LEVIN_PACKET partial msg received. len=" << cb << ", current total " << m_cache_in_buffer.size() << "/" << m_current_head.m_cb << " (" << (100.0f * m_cache_in_buffer.size() / (m_current_head.m_cb ? m_current_head.m_cb : 1)) << "%)");
|
||||
MDEBUG(m_connection_context << "LEVIN_PACKET partial msg received. len=" << cb);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -485,14 +465,6 @@ public:
|
||||
temp = std::move(m_fragment_buffer);
|
||||
m_fragment_buffer.clear();
|
||||
std::memcpy(std::addressof(m_current_head), std::addressof(temp[0]), sizeof(bucket_head2));
|
||||
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
|
||||
if(m_current_head.m_cb > std::min<size_t>(max_packet_size, max_bytes))
|
||||
{
|
||||
MERROR(m_connection_context << "Maximum packet size exceed!, m_max_packet_size = " << std::min<size_t>(max_packet_size, max_bytes)
|
||||
<< ", packet header received " << m_current_head.m_cb << ", command " << m_current_head.m_command
|
||||
<< ", connection will be closed.");
|
||||
return false;
|
||||
}
|
||||
buff_to_invoke = {reinterpret_cast<const uint8_t*>(temp.data()) + sizeof(bucket_head2), temp.size() - sizeof(bucket_head2)};
|
||||
}
|
||||
|
||||
@@ -542,17 +514,23 @@ public:
|
||||
{
|
||||
if(m_current_head.m_have_to_return_data)
|
||||
{
|
||||
levin::message_writer return_message{32 * 1024};
|
||||
std::string return_buff;
|
||||
const uint32_t return_code = m_config.m_pcommands_handler->invoke(
|
||||
m_current_head.m_command, buff_to_invoke, return_message.buffer, m_connection_context
|
||||
m_current_head.m_command, buff_to_invoke, return_buff, m_connection_context
|
||||
);
|
||||
|
||||
// peer_id remains unset if dropped
|
||||
if (m_current_head.m_command == m_connection_context.handshake_command() && m_connection_context.handshake_complete())
|
||||
m_max_packet_size = m_config.m_max_packet_size;
|
||||
bucket_head2 head = make_header(m_current_head.m_command, return_buff.size(), LEVIN_PACKET_RESPONSE, false);
|
||||
head.m_return_code = SWAP32LE(return_code);
|
||||
return_buff.insert(0, reinterpret_cast<const char*>(&head), sizeof(head));
|
||||
|
||||
if(!send_message(return_message.finalize_response(m_current_head.m_command, return_code)))
|
||||
if(!m_pservice_endpoint->do_send(byte_slice{std::move(return_buff)}))
|
||||
return false;
|
||||
|
||||
MDEBUG(m_connection_context << "LEVIN_PACKET_SENT. [len=" << head.m_cb
|
||||
<< ", flags" << head.m_flags
|
||||
<< ", r?=" << head.m_have_to_return_data
|
||||
<<", cmd = " << head.m_command
|
||||
<< ", ver=" << head.m_protocol_version);
|
||||
}
|
||||
else
|
||||
m_config.m_pcommands_handler->notify(m_current_head.m_command, buff_to_invoke, m_connection_context);
|
||||
@@ -599,11 +577,10 @@ public:
|
||||
m_cache_in_buffer.erase(sizeof(bucket_head2));
|
||||
m_state = stream_state_body;
|
||||
m_oponent_protocol_ver = m_current_head.m_protocol_version;
|
||||
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
|
||||
if(m_current_head.m_cb > std::min<size_t>(max_packet_size, max_bytes))
|
||||
if(m_current_head.m_cb > m_config.m_max_packet_size)
|
||||
{
|
||||
LOG_ERROR_CC(m_connection_context, "Maximum packet size exceed!, m_max_packet_size = " << std::min<size_t>(max_packet_size, max_bytes)
|
||||
<< ", packet header received " << m_current_head.m_cb << ", command " << m_current_head.m_command
|
||||
LOG_ERROR_CC(m_connection_context, "Maximum packet size exceed!, m_max_packet_size = " << m_config.m_max_packet_size
|
||||
<< ", packet header received " << m_current_head.m_cb
|
||||
<< ", connection will be closed.");
|
||||
return false;
|
||||
}
|
||||
@@ -629,7 +606,7 @@ public:
|
||||
}
|
||||
|
||||
template<class callback_t>
|
||||
bool async_invoke(int command, message_writer in_msg, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
|
||||
bool async_invoke(int command, const epee::span<const uint8_t> in_buff, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
|
||||
{
|
||||
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler(
|
||||
boost::bind(&async_protocol_handler::finish_outer_call, this));
|
||||
@@ -640,15 +617,24 @@ public:
|
||||
int err_code = LEVIN_OK;
|
||||
do
|
||||
{
|
||||
if(m_deletion_initiated)
|
||||
{
|
||||
err_code = LEVIN_ERROR_CONNECTION_DESTROYED;
|
||||
break;
|
||||
}
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_call_lock);
|
||||
|
||||
if(m_deletion_initiated)
|
||||
{
|
||||
err_code = LEVIN_ERROR_CONNECTION_DESTROYED;
|
||||
break;
|
||||
}
|
||||
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_buf_ready, 0);
|
||||
CRITICAL_REGION_BEGIN(m_invoke_response_handlers_lock);
|
||||
|
||||
if (command == m_connection_context.handshake_command())
|
||||
m_max_packet_size = m_config.m_max_packet_size;
|
||||
|
||||
if(!send_message(in_msg.finalize_invoke(command)))
|
||||
if(!send_message(command, in_buff, LEVIN_PACKET_REQUEST, true))
|
||||
{
|
||||
LOG_ERROR_CC(m_connection_context, "Failed to do_send");
|
||||
err_code = LEVIN_ERROR_CONNECTION;
|
||||
@@ -674,19 +660,22 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
int invoke(int command, message_writer in_msg, std::string& buff_out)
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out)
|
||||
{
|
||||
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler(
|
||||
boost::bind(&async_protocol_handler::finish_outer_call, this));
|
||||
|
||||
if(m_deletion_initiated)
|
||||
return LEVIN_ERROR_CONNECTION_DESTROYED;
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_call_lock);
|
||||
|
||||
if(m_deletion_initiated)
|
||||
return LEVIN_ERROR_CONNECTION_DESTROYED;
|
||||
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_buf_ready, 0);
|
||||
|
||||
if (command == m_connection_context.handshake_command())
|
||||
m_max_packet_size = m_config.m_max_packet_size;
|
||||
|
||||
if (!send_message(in_msg.finalize_invoke(command)))
|
||||
if (!send_message(command, in_buff, LEVIN_PACKET_REQUEST, true))
|
||||
{
|
||||
LOG_ERROR_CC(m_connection_context, "Failed to send request");
|
||||
return LEVIN_ERROR_CONNECTION;
|
||||
@@ -695,7 +684,7 @@ public:
|
||||
uint64_t ticks_start = misc_utils::get_tick_count();
|
||||
size_t prev_size = 0;
|
||||
|
||||
while(!boost::interprocess::ipcdetail::atomic_read32(&m_invoke_buf_ready) && !m_protocol_released)
|
||||
while(!boost::interprocess::ipcdetail::atomic_read32(&m_invoke_buf_ready) && !m_deletion_initiated && !m_protocol_released)
|
||||
{
|
||||
if(m_cache_in_buffer.size() - prev_size >= MIN_BYTES_WANTED)
|
||||
{
|
||||
@@ -712,7 +701,7 @@ public:
|
||||
return LEVIN_ERROR_CONNECTION_DESTROYED;
|
||||
}
|
||||
|
||||
if(m_protocol_released)
|
||||
if(m_deletion_initiated || m_protocol_released)
|
||||
return LEVIN_ERROR_CONNECTION_DESTROYED;
|
||||
|
||||
CRITICAL_REGION_BEGIN(m_local_inv_buff_lock);
|
||||
@@ -723,9 +712,31 @@ public:
|
||||
return m_invoke_result_code;
|
||||
}
|
||||
|
||||
/*! Sends `message` without adding a levin header. The message must have been
|
||||
created with `make_noise_notify`, `make_fragmented_notify`, or
|
||||
`message_writer::finalize_notify`. See additional instructions for
|
||||
int notify(int command, const epee::span<const uint8_t> in_buff)
|
||||
{
|
||||
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler(
|
||||
boost::bind(&async_protocol_handler::finish_outer_call, this));
|
||||
|
||||
if(m_deletion_initiated)
|
||||
return LEVIN_ERROR_CONNECTION_DESTROYED;
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_call_lock);
|
||||
|
||||
if(m_deletion_initiated)
|
||||
return LEVIN_ERROR_CONNECTION_DESTROYED;
|
||||
|
||||
if (!send_message(command, in_buff, LEVIN_PACKET_REQUEST, false))
|
||||
{
|
||||
LOG_ERROR_CC(m_connection_context, "Failed to send notify message");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*! Sends `message` without adding a levin header. The message must have
|
||||
been created with `make_notify`, `make_noise_notify` or
|
||||
`make_fragmented_notify`. See additional instructions for
|
||||
`make_fragmented_notify`.
|
||||
|
||||
\return 1 on success */
|
||||
@@ -735,11 +746,17 @@ public:
|
||||
boost::bind(&async_protocol_handler::finish_outer_call, this)
|
||||
);
|
||||
|
||||
if (!send_message(std::move(message)))
|
||||
if(m_deletion_initiated)
|
||||
return LEVIN_ERROR_CONNECTION_DESTROYED;
|
||||
|
||||
const std::size_t length = message.size();
|
||||
if (!m_pservice_endpoint->do_send(std::move(message)))
|
||||
{
|
||||
LOG_ERROR_CC(m_connection_context, "Failed to send message, dropping it");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MDEBUG(m_connection_context << "LEVIN_PACKET_SENT. [len=" << (length - sizeof(bucket_head2)) << ", r?=0]");
|
||||
return 1;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
@@ -760,32 +777,36 @@ void async_protocol_handler_config<t_connection_context>::del_connection(async_p
|
||||
template<class t_connection_context>
|
||||
void async_protocol_handler_config<t_connection_context>::delete_connections(size_t count, bool incoming)
|
||||
{
|
||||
std::vector<typename connections_map::mapped_type> connections;
|
||||
|
||||
auto scope_exit_handler = misc_utils::create_scope_leave_handler([&connections]{
|
||||
for (auto &aph: connections)
|
||||
aph->finish_outer_call();
|
||||
});
|
||||
|
||||
std::vector <boost::uuids::uuid> connections;
|
||||
CRITICAL_REGION_BEGIN(m_connects_lock);
|
||||
for (auto& c: m_connects)
|
||||
{
|
||||
if (c.second->m_connection_context.m_is_income == incoming)
|
||||
if (c.second->start_outer_call())
|
||||
connections.push_back(c.second);
|
||||
connections.push_back(c.first);
|
||||
}
|
||||
|
||||
// close random connections from the provided set
|
||||
// TODO or better just keep removing random elements (performance)
|
||||
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||
shuffle(connections.begin(), connections.end(), std::default_random_engine(seed));
|
||||
for (size_t i = 0; i < connections.size() && i < count; ++i)
|
||||
m_connects.erase(connections[i]->get_connection_id());
|
||||
while (count > 0 && connections.size() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto i = connections.end() - 1;
|
||||
async_protocol_handler<t_connection_context> *conn = m_connects.at(*i);
|
||||
del_connection(conn);
|
||||
conn->close();
|
||||
connections.erase(i);
|
||||
}
|
||||
catch (const std::out_of_range &e)
|
||||
{
|
||||
MWARNING("Connection not found in m_connects, continuing");
|
||||
}
|
||||
--count;
|
||||
}
|
||||
|
||||
CRITICAL_REGION_END();
|
||||
|
||||
for (size_t i = 0; i < connections.size() && i < count; ++i)
|
||||
connections[i]->close();
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context>
|
||||
@@ -829,53 +850,41 @@ int async_protocol_handler_config<t_connection_context>::find_and_lock_connectio
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context>
|
||||
int async_protocol_handler_config<t_connection_context>::invoke(int command, message_writer in_msg, std::string& buff_out, boost::uuids::uuid connection_id)
|
||||
int async_protocol_handler_config<t_connection_context>::invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, boost::uuids::uuid connection_id)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph;
|
||||
int r = find_and_lock_connection(connection_id, aph);
|
||||
return LEVIN_OK == r ? aph->invoke(command, std::move(in_msg), buff_out) : r;
|
||||
return LEVIN_OK == r ? aph->invoke(command, in_buff, buff_out) : r;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context> template<class callback_t>
|
||||
int async_protocol_handler_config<t_connection_context>::invoke_async(int command, message_writer in_msg, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout)
|
||||
int async_protocol_handler_config<t_connection_context>::invoke_async(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph;
|
||||
int r = find_and_lock_connection(connection_id, aph);
|
||||
return LEVIN_OK == r ? aph->async_invoke(command, std::move(in_msg), cb, timeout) : r;
|
||||
return LEVIN_OK == r ? aph->async_invoke(command, in_buff, cb, timeout) : r;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context> template<class callback_t>
|
||||
bool async_protocol_handler_config<t_connection_context>::foreach_connection(const callback_t &cb)
|
||||
{
|
||||
std::vector<typename connections_map::mapped_type> conn;
|
||||
|
||||
auto scope_exit_handler = misc_utils::create_scope_leave_handler([&conn]{
|
||||
for (auto &aph: conn)
|
||||
aph->finish_outer_call();
|
||||
});
|
||||
|
||||
CRITICAL_REGION_BEGIN(m_connects_lock);
|
||||
conn.reserve(m_connects.size());
|
||||
for (auto &e: m_connects)
|
||||
if (e.second->start_outer_call())
|
||||
conn.push_back(e.second);
|
||||
CRITICAL_REGION_END()
|
||||
|
||||
for (auto &aph: conn)
|
||||
if (!cb(aph->get_context_ref()))
|
||||
CRITICAL_REGION_LOCAL(m_connects_lock);
|
||||
for(auto& c: m_connects)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph = c.second;
|
||||
if(!cb(aph->get_context_ref()))
|
||||
return false;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context> template<class callback_t>
|
||||
bool async_protocol_handler_config<t_connection_context>::for_connection(const boost::uuids::uuid &connection_id, const callback_t &cb)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph = nullptr;
|
||||
if (find_and_lock_connection(connection_id, aph) != LEVIN_OK)
|
||||
CRITICAL_REGION_LOCAL(m_connects_lock);
|
||||
async_protocol_handler<t_connection_context>* aph = find_connection(connection_id);
|
||||
if (!aph)
|
||||
return false;
|
||||
auto scope_exit_handler = misc_utils::create_scope_leave_handler(
|
||||
boost::bind(&async_protocol_handler<t_connection_context>::finish_outer_call, aph));
|
||||
if(!cb(aph->get_context_ref()))
|
||||
return false;
|
||||
return true;
|
||||
@@ -920,6 +929,14 @@ void async_protocol_handler_config<t_connection_context>::set_handler(levin_comm
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context>
|
||||
int async_protocol_handler_config<t_connection_context>::notify(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph;
|
||||
int r = find_and_lock_connection(connection_id, aph);
|
||||
return LEVIN_OK == r ? aph->notify(command, in_buff) : r;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context>
|
||||
int async_protocol_handler_config<t_connection_context>::send(byte_slice message, const boost::uuids::uuid& connection_id)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph;
|
||||
@@ -930,14 +947,12 @@ int async_protocol_handler_config<t_connection_context>::send(byte_slice message
|
||||
template<class t_connection_context>
|
||||
bool async_protocol_handler_config<t_connection_context>::close(boost::uuids::uuid connection_id)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph = nullptr;
|
||||
if (find_and_lock_connection(connection_id, aph) != LEVIN_OK)
|
||||
CRITICAL_REGION_LOCAL(m_connects_lock);
|
||||
async_protocol_handler<t_connection_context>* aph = find_connection(connection_id);
|
||||
if (!aph)
|
||||
return false;
|
||||
auto scope_exit_handler = misc_utils::create_scope_leave_handler(
|
||||
boost::bind(&async_protocol_handler<t_connection_context>::finish_outer_call, aph));
|
||||
if (!aph->close())
|
||||
return false;
|
||||
CRITICAL_REGION_LOCAL(m_connects_lock);
|
||||
m_connects.erase(connection_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/interprocess/detail/atomic.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <functional>
|
||||
#include "net/net_utils_base.h"
|
||||
#include "net/net_ssl.h"
|
||||
@@ -179,7 +178,7 @@ namespace net_utils
|
||||
// SSL Options
|
||||
if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, {}, addr, timeout))
|
||||
if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, addr, timeout))
|
||||
{
|
||||
if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
@@ -281,7 +280,7 @@ namespace net_utils
|
||||
|
||||
|
||||
inline
|
||||
bool send(const boost::string_ref buff, std::chrono::milliseconds timeout)
|
||||
bool send(const std::string& buff, std::chrono::milliseconds timeout)
|
||||
{
|
||||
|
||||
try
|
||||
@@ -299,7 +298,7 @@ namespace net_utils
|
||||
// object is used as a callback and will update the ec variable when the
|
||||
// operation completes. The blocking_udp_client.cpp example shows how you
|
||||
// can use boost::bind rather than boost::lambda.
|
||||
async_write(buff.data(), buff.size(), ec);
|
||||
async_write(buff.c_str(), buff.size(), ec);
|
||||
|
||||
// Block until the asynchronous operation has completed.
|
||||
while (ec == boost::asio::error::would_block)
|
||||
|
||||
@@ -24,9 +24,12 @@
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "http_base.h"
|
||||
#include "reg_exp_definer.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net"
|
||||
@@ -35,8 +38,173 @@ namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
bool parse_uri(const std::string uri, http::uri_content& content);
|
||||
bool parse_url_ipv6(const std::string url_str, http::url_content& content);
|
||||
bool parse_url(const std::string url_str, http::url_content& content);
|
||||
|
||||
inline bool parse_uri_query(const std::string& query, std::list<std::pair<std::string, std::string> >& params)
|
||||
{
|
||||
enum state
|
||||
{
|
||||
st_param_name,
|
||||
st_param_val
|
||||
};
|
||||
state st = st_param_name;
|
||||
std::string::const_iterator start_it = query.begin();
|
||||
std::pair<std::string, std::string> e;
|
||||
for(std::string::const_iterator it = query.begin(); it != query.end(); it++)
|
||||
{
|
||||
switch(st)
|
||||
{
|
||||
case st_param_name:
|
||||
if(*it == '=')
|
||||
{
|
||||
e.first.assign(start_it, it);
|
||||
start_it = it;++start_it;
|
||||
st = st_param_val;
|
||||
}
|
||||
break;
|
||||
case st_param_val:
|
||||
if(*it == '&')
|
||||
{
|
||||
e.second.assign(start_it, it);
|
||||
start_it = it;++start_it;
|
||||
params.push_back(e);
|
||||
e.first.clear();e.second.clear();
|
||||
st = st_param_name;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unknown state " << (int)st);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(st == st_param_name)
|
||||
{
|
||||
if(start_it != query.end())
|
||||
{
|
||||
e.first.assign(start_it, query.end());
|
||||
params.push_back(e);
|
||||
}
|
||||
}else
|
||||
{
|
||||
if(start_it != query.end())
|
||||
e.second.assign(start_it, query.end());
|
||||
|
||||
if(e.first.size())
|
||||
params.push_back(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
bool parse_uri(const std::string uri, http::uri_content& content)
|
||||
{
|
||||
|
||||
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
|
||||
content.m_query_params.clear();
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
|
||||
|
||||
boost::smatch result;
|
||||
if(!(boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched))
|
||||
{
|
||||
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri);
|
||||
content.m_path = uri;
|
||||
return true;
|
||||
}
|
||||
if(result[1].matched)
|
||||
{
|
||||
content.m_path = result[1];
|
||||
}
|
||||
if(result[3].matched)
|
||||
{
|
||||
content.m_query = result[3];
|
||||
}
|
||||
if(result[5].matched)
|
||||
{
|
||||
content.m_fragment = result[5];
|
||||
}
|
||||
if(content.m_query.size())
|
||||
{
|
||||
parse_uri_query(content.m_query, content.m_query_params);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
bool parse_url_ipv6(const std::string url_str, http::url_content& content)
|
||||
{
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^((.*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
|
||||
// 12 3 4 5 6 7
|
||||
|
||||
content.port = 0;
|
||||
boost::smatch result;
|
||||
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
|
||||
{
|
||||
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
|
||||
//content.m_path = uri;
|
||||
return false;
|
||||
}
|
||||
if(result[2].matched)
|
||||
{
|
||||
content.schema = result[2];
|
||||
}
|
||||
if(result[4].matched)
|
||||
{
|
||||
content.host = result[4];
|
||||
}
|
||||
else // if host not matched, matching should be considered failed
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(result[6].matched)
|
||||
{
|
||||
content.port = boost::lexical_cast<uint64_t>(result[6]);
|
||||
}
|
||||
if(result[7].matched)
|
||||
{
|
||||
content.uri = result[7];
|
||||
return parse_uri(result[7], content.m_uri_content);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
bool parse_url(const std::string url_str, http::url_content& content)
|
||||
{
|
||||
|
||||
if (parse_url_ipv6(url_str, content)) return true;
|
||||
|
||||
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
|
||||
//STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^((.*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
|
||||
// 12 34 5 6 7
|
||||
content.port = 0;
|
||||
boost::smatch result;
|
||||
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
|
||||
{
|
||||
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
|
||||
//content.m_path = uri;
|
||||
return true;
|
||||
}
|
||||
if(result[2].matched)
|
||||
{
|
||||
content.schema = result[2];
|
||||
}
|
||||
if(result[4].matched)
|
||||
{
|
||||
content.host = result[4];
|
||||
}
|
||||
if(result[6].matched)
|
||||
{
|
||||
content.port = boost::lexical_cast<uint64_t>(result[6]);
|
||||
}
|
||||
if(result[7].matched)
|
||||
{
|
||||
content.uri = result[7];
|
||||
return parse_uri(result[7], content.m_uri_content);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#define SSL_FINGERPRINT_SIZE 32
|
||||
@@ -133,7 +132,6 @@ namespace net_utils
|
||||
bool handshake(
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket,
|
||||
boost::asio::ssl::stream_base::handshake_type type,
|
||||
boost::asio::const_buffer buffer = {},
|
||||
const std::string& host = {},
|
||||
std::chrono::milliseconds timeout = std::chrono::seconds(15)) const;
|
||||
};
|
||||
@@ -145,9 +143,6 @@ namespace net_utils
|
||||
|
||||
bool create_ec_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
|
||||
bool create_rsa_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
|
||||
|
||||
//! Store private key for `ssl` at `base + ".key"` unencrypted and certificate for `ssl` at `base + ".crt"`.
|
||||
boost::system::error_code store_ssl_keys(boost::asio::ssl::context& ssl, const boost::filesystem::path& base);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#define _REG_EXP_DEFINER_H_
|
||||
|
||||
#include <boost/interprocess/detail/atomic.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include "syncobj.h"
|
||||
|
||||
namespace epee
|
||||
|
||||
@@ -141,6 +141,7 @@ public:
|
||||
|
||||
rolling_median_t(rolling_median_t &&m)
|
||||
{
|
||||
free(data);
|
||||
memcpy(this, &m, sizeof(rolling_median_t));
|
||||
m.data = NULL;
|
||||
}
|
||||
|
||||
@@ -73,8 +73,7 @@ public: \
|
||||
template<bool is_store, class t_storage> \
|
||||
bool serialize_map(t_storage& stg, typename t_storage::hsection hparent_section) \
|
||||
{ \
|
||||
decltype(*this) &this_ref = *this; \
|
||||
(void) this_ref; // Suppress unused var warnings. Sometimes this var is used, sometimes not.
|
||||
decltype(*this) &this_ref = *this;
|
||||
|
||||
#define KV_SERIALIZE_N(varialble, val_name) \
|
||||
epee::serialization::selector<is_store>::serialize(this_ref.varialble, stg, hparent_section, val_name);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace epee
|
||||
@@ -166,11 +167,10 @@ namespace epee
|
||||
}
|
||||
|
||||
//! make a span from a std::string
|
||||
template<typename T, typename U>
|
||||
span<const T> strspan(const U&s) noexcept
|
||||
template<typename T>
|
||||
span<const T> strspan(const std::string &s) noexcept
|
||||
{
|
||||
static_assert(std::is_same<typename U::value_type, char>(), "unexpected source type");
|
||||
static_assert(std::is_same<T, char>() || std::is_same<T, unsigned char>() || std::is_same<T, int8_t>() || std::is_same<T, uint8_t>(), "Unexpected destination type");
|
||||
static_assert(std::is_same<T, char>() || std::is_same<T, unsigned char>() || std::is_same<T, int8_t>() || std::is_same<T, uint8_t>(), "Unexpected type");
|
||||
return {reinterpret_cast<const T*>(s.data()), s.size()};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include "byte_slice.h"
|
||||
#include "portable_storage_template_helper.h"
|
||||
#include "net/http_base.h"
|
||||
#include "net/http_server_handlers_map2.h"
|
||||
@@ -75,12 +74,12 @@ namespace epee
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_bin(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "POST")
|
||||
{
|
||||
byte_slice req_param;
|
||||
if(!serialization::store_t_to_binary(out_struct, req_param, 16 * 1024))
|
||||
std::string req_param;
|
||||
if(!serialization::store_t_to_binary(out_struct, req_param))
|
||||
return false;
|
||||
|
||||
const http::http_response_info* pri = NULL;
|
||||
if(!transport.invoke(uri, method, boost::string_ref{reinterpret_cast<const char*>(req_param.data()), req_param.size()}, timeout, std::addressof(pri)))
|
||||
if(!transport.invoke(uri, method, req_param, timeout, std::addressof(pri)))
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke http request to " << uri);
|
||||
return false;
|
||||
@@ -98,12 +97,7 @@ namespace epee
|
||||
return false;
|
||||
}
|
||||
|
||||
static const constexpr epee::serialization::portable_storage::limits_t default_http_bin_limits = {
|
||||
65536 * 3, // objects
|
||||
65536 * 3, // fields
|
||||
65536 * 3, // strings
|
||||
};
|
||||
return serialization::load_t_from_binary(result_struct, epee::strspan<uint8_t>(pri->m_body), &default_http_bin_limits);
|
||||
return serialization::load_t_from_binary(result_struct, epee::strspan<uint8_t>(pri->m_body));
|
||||
}
|
||||
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
|
||||
@@ -27,29 +27,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "portable_storage_template_helper.h"
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include <functional>
|
||||
#include "byte_slice.h"
|
||||
#include "span.h"
|
||||
#include "net/levin_base.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net"
|
||||
|
||||
template<typename context_t>
|
||||
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, const char *category);
|
||||
|
||||
template<typename context_t>
|
||||
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, int command);
|
||||
|
||||
namespace
|
||||
{
|
||||
static const constexpr epee::serialization::portable_storage::limits_t default_levin_limits = {
|
||||
8192, // objects
|
||||
16384, // fields
|
||||
16384, // strings
|
||||
};
|
||||
template<typename context_t>
|
||||
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, const char *category)
|
||||
{
|
||||
MCINFO("net.p2p.traffic", context << bytes << " bytes " << (sent ? "sent" : "received") << (error ? "/corrupt" : "")
|
||||
<< " for category " << category << " initiated by " << (initiator ? "us" : "peer"));
|
||||
}
|
||||
template<typename context_t>
|
||||
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, int command)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "command-%u", command);
|
||||
return on_levin_traffic(context, initiator, sent, error, bytes, buf);
|
||||
}
|
||||
}
|
||||
|
||||
namespace epee
|
||||
@@ -75,7 +75,7 @@ namespace epee
|
||||
return false;
|
||||
}
|
||||
serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff_to_recv, &default_levin_limits))
|
||||
if(!stg_ret.load_from_binary(buff_to_recv))
|
||||
{
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
return false;
|
||||
@@ -110,18 +110,18 @@ namespace epee
|
||||
const boost::uuids::uuid &conn_id = context.m_connection_id;
|
||||
typename serialization::portable_storage stg;
|
||||
out_struct.store(stg);
|
||||
levin::message_writer to_send{16 * 1024};
|
||||
std::string buff_to_recv;
|
||||
stg.store_to_binary(to_send.buffer);
|
||||
std::string buff_to_send, buff_to_recv;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
|
||||
int res = transport.invoke(command, std::move(to_send), buff_to_recv, conn_id);
|
||||
on_levin_traffic(context, true, true, false, buff_to_send.size(), command);
|
||||
int res = transport.invoke(command, buff_to_send, buff_to_recv, conn_id);
|
||||
if( res <=0 )
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke command " << command << " return code " << res);
|
||||
return false;
|
||||
}
|
||||
typename serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff_to_recv, &default_levin_limits))
|
||||
if(!stg_ret.load_from_binary(buff_to_recv))
|
||||
{
|
||||
on_levin_traffic(context, true, false, true, buff_to_recv.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
@@ -137,9 +137,10 @@ namespace epee
|
||||
const boost::uuids::uuid &conn_id = context.m_connection_id;
|
||||
typename serialization::portable_storage stg;
|
||||
const_cast<t_arg&>(out_struct).store(stg);//TODO: add true const support to searilzation
|
||||
levin::message_writer to_send{16 * 1024};
|
||||
stg.store_to_binary(to_send.buffer);
|
||||
int res = transport.invoke_async(command, std::move(to_send), conn_id, [cb, command](int code, const epee::span<const uint8_t> buff, typename t_transport::connection_context& context)->bool
|
||||
std::string buff_to_send;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
on_levin_traffic(context, true, true, false, buff_to_send.size(), command);
|
||||
int res = transport.invoke_async(command, epee::strspan<uint8_t>(buff_to_send), conn_id, [cb, command](int code, const epee::span<const uint8_t> buff, typename t_transport::connection_context& context)->bool
|
||||
{
|
||||
t_result result_struct = AUTO_VAL_INIT(result_struct);
|
||||
if( code <=0 )
|
||||
@@ -151,7 +152,7 @@ namespace epee
|
||||
return false;
|
||||
}
|
||||
serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff, &default_levin_limits))
|
||||
if(!stg_ret.load_from_binary(buff))
|
||||
{
|
||||
on_levin_traffic(context, true, false, true, buff.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
@@ -183,10 +184,11 @@ namespace epee
|
||||
const boost::uuids::uuid &conn_id = context.m_connection_id;
|
||||
serialization::portable_storage stg;
|
||||
out_struct.store(stg);
|
||||
levin::message_writer to_send;
|
||||
stg.store_to_binary(to_send.buffer);
|
||||
std::string buff_to_send;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
|
||||
int res = transport.send(to_send.finalize_notify(command), conn_id);
|
||||
on_levin_traffic(context, true, true, false, buff_to_send.size(), command);
|
||||
int res = transport.notify(command, epee::strspan<uint8_t>(buff_to_send), conn_id);
|
||||
if(res <=0 )
|
||||
{
|
||||
MERROR("Failed to notify command " << command << " return code " << res);
|
||||
@@ -197,10 +199,10 @@ namespace epee
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template<class t_owner, class t_in_type, class t_out_type, class t_context, class callback_t>
|
||||
int buff_to_t_adapter(int command, const epee::span<const uint8_t> in_buff, byte_stream& buff_out, callback_t cb, t_context& context )
|
||||
int buff_to_t_adapter(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, callback_t cb, t_context& context )
|
||||
{
|
||||
serialization::portable_storage strg;
|
||||
if(!strg.load_from_binary(in_buff, &default_levin_limits))
|
||||
if(!strg.load_from_binary(in_buff))
|
||||
{
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary in command " << command);
|
||||
@@ -225,6 +227,7 @@ namespace epee
|
||||
LOG_ERROR("Failed to store_to_binary in command" << command);
|
||||
return -1;
|
||||
}
|
||||
on_levin_traffic(context, false, true, false, buff_out.size(), command);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -233,7 +236,7 @@ namespace epee
|
||||
int buff_to_t_adapter(t_owner* powner, int command, const epee::span<const uint8_t> in_buff, callback_t cb, t_context& context)
|
||||
{
|
||||
serialization::portable_storage strg;
|
||||
if(!strg.load_from_binary(in_buff, &default_levin_limits))
|
||||
if(!strg.load_from_binary(in_buff))
|
||||
{
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary in notify " << command);
|
||||
@@ -251,7 +254,7 @@ namespace epee
|
||||
}
|
||||
|
||||
#define CHAIN_LEVIN_INVOKE_MAP2(context_type) \
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, epee::byte_stream& buff_out, context_type& context) \
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, context_type& context) \
|
||||
{ \
|
||||
bool handled = false; \
|
||||
return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \
|
||||
@@ -260,13 +263,13 @@ namespace epee
|
||||
#define CHAIN_LEVIN_NOTIFY_MAP2(context_type) \
|
||||
int notify(int command, const epee::span<const uint8_t> in_buff, context_type& context) \
|
||||
{ \
|
||||
bool handled = false; epee::byte_stream fake_str; \
|
||||
return handle_invoke_map(true, command, in_buff, fake_str, context, handled); \
|
||||
bool handled = false; std::string fake_str;\
|
||||
return handle_invoke_map(true, command, in_buff, fake_str, context, handled); \
|
||||
}
|
||||
|
||||
|
||||
#define CHAIN_LEVIN_INVOKE_MAP() \
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, epee::byte_stream& buff_out, epee::net_utils::connection_context_base& context) \
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, epee::net_utils::connection_context_base& context) \
|
||||
{ \
|
||||
bool handled = false; \
|
||||
return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \
|
||||
@@ -286,7 +289,7 @@ namespace epee
|
||||
}
|
||||
|
||||
#define BEGIN_INVOKE_MAP2(owner_type) \
|
||||
template <class t_context> int handle_invoke_map(bool is_notify, int command, const epee::span<const uint8_t> in_buff, epee::byte_stream& buff_out, t_context& context, bool& handled) \
|
||||
template <class t_context> int handle_invoke_map(bool is_notify, int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, t_context& context, bool& handled) \
|
||||
{ \
|
||||
try { \
|
||||
typedef owner_type internal_owner_type_name;
|
||||
|
||||
@@ -28,8 +28,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/utility/string_ref_fwd.hpp>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
@@ -92,7 +97,46 @@ namespace misc_utils
|
||||
return lut[(uint8_t)c] & 1;
|
||||
}
|
||||
|
||||
std::string transform_to_escape_sequence(const std::string& src);
|
||||
inline std::string transform_to_escape_sequence(const std::string& src)
|
||||
{
|
||||
static const char escaped[] = "\b\f\n\r\t\v\"\\/";
|
||||
std::string::const_iterator it = std::find_first_of(src.begin(), src.end(), escaped, escaped + sizeof(escaped));
|
||||
if (it == src.end())
|
||||
return src;
|
||||
|
||||
std::string res;
|
||||
res.reserve(2 * src.size());
|
||||
res.assign(src.begin(), it);
|
||||
for(; it!=src.end(); ++it)
|
||||
{
|
||||
switch(*it)
|
||||
{
|
||||
case '\b': //Backspace (ascii code 08)
|
||||
res+="\\b"; break;
|
||||
case '\f': //Form feed (ascii code 0C)
|
||||
res+="\\f"; break;
|
||||
case '\n': //New line
|
||||
res+="\\n"; break;
|
||||
case '\r': //Carriage return
|
||||
res+="\\r"; break;
|
||||
case '\t': //Tab
|
||||
res+="\\t"; break;
|
||||
case '\v': //Vertical tab
|
||||
res+="\\v"; break;
|
||||
//case '\'': //Apostrophe or single quote
|
||||
// res+="\\'"; break;
|
||||
case '"': //Double quote
|
||||
res+="\\\""; break;
|
||||
case '\\': //Backslash caracter
|
||||
res+="\\\\"; break;
|
||||
case '/': //Backslash caracter
|
||||
res+="\\/"; break;
|
||||
default:
|
||||
res.push_back(*it);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/*
|
||||
|
||||
\b Backspace (ascii code 08)
|
||||
@@ -106,7 +150,98 @@ namespace misc_utils
|
||||
\\ Backslash character
|
||||
|
||||
*/
|
||||
void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val);
|
||||
inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
bool escape_mode = false;
|
||||
std::string::const_iterator it = star_end_string;
|
||||
++it;
|
||||
std::string::const_iterator fi = it;
|
||||
while (fi != buf_end && ((lut[(uint8_t)*fi] & 32)) == 0)
|
||||
++fi;
|
||||
val.assign(it, fi);
|
||||
it = fi;
|
||||
for(;it != buf_end;it++)
|
||||
{
|
||||
if(escape_mode/*prev_ch == '\\'*/)
|
||||
{
|
||||
switch(*it)
|
||||
{
|
||||
case 'b': //Backspace (ascii code 08)
|
||||
val.push_back(0x08);break;
|
||||
case 'f': //Form feed (ascii code 0C)
|
||||
val.push_back(0x0C);break;
|
||||
case 'n': //New line
|
||||
val.push_back('\n');break;
|
||||
case 'r': //Carriage return
|
||||
val.push_back('\r');break;
|
||||
case 't': //Tab
|
||||
val.push_back('\t');break;
|
||||
case 'v': //Vertical tab
|
||||
val.push_back('\v');break;
|
||||
case '\'': //Apostrophe or single quote
|
||||
val.push_back('\'');break;
|
||||
case '"': //Double quote
|
||||
val.push_back('"');break;
|
||||
case '\\': //Backslash character
|
||||
val.push_back('\\');break;
|
||||
case '/': //Slash character
|
||||
val.push_back('/');break;
|
||||
case 'u': //Unicode code point
|
||||
if (buf_end - it < 4)
|
||||
{
|
||||
ASSERT_MES_AND_THROW("Invalid Unicode escape sequence");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dst = 0;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
const unsigned char tmp = isx[(unsigned char)*++it];
|
||||
CHECK_AND_ASSERT_THROW_MES(tmp != 0xff, "Bad Unicode encoding");
|
||||
dst = dst << 4 | tmp;
|
||||
}
|
||||
// encode as UTF-8
|
||||
if (dst <= 0x7f)
|
||||
{
|
||||
val.push_back(dst);
|
||||
}
|
||||
else if (dst <= 0x7ff)
|
||||
{
|
||||
val.push_back(0xc0 | (dst >> 6));
|
||||
val.push_back(0x80 | (dst & 0x3f));
|
||||
}
|
||||
else if (dst <= 0xffff)
|
||||
{
|
||||
val.push_back(0xe0 | (dst >> 12));
|
||||
val.push_back(0x80 | ((dst >> 6) & 0x3f));
|
||||
val.push_back(0x80 | (dst & 0x3f));
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_MES_AND_THROW("Unicode code point is out or range");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
val.push_back(*it);
|
||||
LOG_PRINT_L0("Unknown escape sequence :\"\\" << *it << "\"");
|
||||
}
|
||||
escape_mode = false;
|
||||
}else if(*it == '"')
|
||||
{
|
||||
star_end_string = it;
|
||||
return;
|
||||
}else if(*it == '\\')
|
||||
{
|
||||
escape_mode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
val.push_back(*it);
|
||||
}
|
||||
}
|
||||
ASSERT_MES_AND_THROW("Failed to match string in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
inline bool match_string(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
try
|
||||
@@ -120,7 +255,42 @@ namespace misc_utils
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void match_number2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val, bool& is_float_val, bool& is_signed_val);
|
||||
inline void match_number2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val, bool& is_float_val, bool& is_signed_val)
|
||||
{
|
||||
val.clear();
|
||||
uint8_t float_flag = 0;
|
||||
is_signed_val = false;
|
||||
size_t chars = 0;
|
||||
std::string::const_iterator it = star_end_string;
|
||||
if (it != buf_end && *it == '-')
|
||||
{
|
||||
is_signed_val = true;
|
||||
++chars;
|
||||
++it;
|
||||
}
|
||||
for(;it != buf_end;it++)
|
||||
{
|
||||
const uint8_t flags = lut[(uint8_t)*it];
|
||||
if (flags & 16)
|
||||
{
|
||||
float_flag |= flags;
|
||||
++chars;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = boost::string_ref(&*star_end_string, chars);
|
||||
if(val.size())
|
||||
{
|
||||
star_end_string = --it;
|
||||
is_float_val = !!(float_flag & 2);
|
||||
return;
|
||||
}
|
||||
else
|
||||
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
}
|
||||
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
inline bool match_number(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
|
||||
{
|
||||
try
|
||||
@@ -134,7 +304,25 @@ namespace misc_utils
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void match_word2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val);
|
||||
inline void match_word2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
|
||||
{
|
||||
val.clear();
|
||||
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if (!(lut[(uint8_t)*it] & 4))
|
||||
{
|
||||
val = boost::string_ref(&*star_end_string, std::distance(star_end_string, it));
|
||||
if(val.size())
|
||||
{
|
||||
star_end_string = --it;
|
||||
return;
|
||||
}else
|
||||
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
}
|
||||
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
inline bool match_word(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
|
||||
{
|
||||
try
|
||||
@@ -147,8 +335,44 @@ namespace misc_utils
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool match_word_with_extrasymb(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val);
|
||||
bool match_word_til_equal_mark(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string::const_iterator& word_end);
|
||||
inline bool match_word_with_extrasymb(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
val.clear();
|
||||
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if(!isalnum(*it) && *it != '-' && *it != '_')
|
||||
{
|
||||
val.assign(star_end_string, it);
|
||||
if(val.size())
|
||||
{
|
||||
star_end_string = --it;
|
||||
return true;
|
||||
}else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline bool match_word_til_equal_mark(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string::const_iterator& word_end)
|
||||
{
|
||||
word_end = star_end_string;
|
||||
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if(isspace(*it))
|
||||
{
|
||||
|
||||
continue;
|
||||
}else if( *it == '=' )
|
||||
{
|
||||
star_end_string = it;
|
||||
word_end = it;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,19 +24,24 @@
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_val_converters.h"
|
||||
#include "misc_log_ex.h"
|
||||
#include "span.h"
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_to_bin.h"
|
||||
#include "portable_storage_from_bin.h"
|
||||
#include "portable_storage_to_json.h"
|
||||
#include "portable_storage_from_json.h"
|
||||
#include "portable_storage_val_converters.h"
|
||||
#include "span.h"
|
||||
#include "int-util.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
class byte_slice;
|
||||
class byte_stream;
|
||||
namespace serialization
|
||||
{
|
||||
/************************************************************************/
|
||||
@@ -49,13 +54,6 @@ namespace epee
|
||||
typedef epee::serialization::harray harray;
|
||||
typedef storage_entry meta_entry;
|
||||
|
||||
struct limits_t
|
||||
{
|
||||
size_t n_objects;
|
||||
size_t n_fields;
|
||||
size_t n_strings; // not counting field names
|
||||
};
|
||||
|
||||
portable_storage(){}
|
||||
virtual ~portable_storage(){}
|
||||
hsection open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist = false);
|
||||
@@ -85,14 +83,9 @@ namespace epee
|
||||
bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool store_to_binary(byte_slice& target, std::size_t initial_buffer_size = 8192);
|
||||
bool store_to_binary(byte_stream& ss);
|
||||
bool load_from_binary(const epee::span<const uint8_t> target, const limits_t *limits = nullptr);
|
||||
bool load_from_binary(const std::string& target, const limits_t *limits = nullptr)
|
||||
{
|
||||
return load_from_binary(epee::strspan<uint8_t>(target), limits);
|
||||
}
|
||||
|
||||
bool store_to_binary(binarybuffer& target);
|
||||
bool load_from_binary(const epee::span<const uint8_t> target);
|
||||
bool load_from_binary(const std::string& target) { return load_from_binary(epee::strspan<uint8_t>(target)); }
|
||||
template<class trace_policy>
|
||||
bool dump_as_xml(std::string& targetObj, const std::string& root_name = "");
|
||||
bool dump_as_json(std::string& targetObj, size_t indent = 0, bool insert_newlines = true);
|
||||
@@ -117,13 +110,99 @@ namespace epee
|
||||
};
|
||||
#pragma pack(pop)
|
||||
};
|
||||
|
||||
inline
|
||||
bool portable_storage::dump_as_json(std::string& buff, size_t indent, bool insert_newlines)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::stringstream ss;
|
||||
epee::serialization::dump_as_json(ss, m_root, indent, insert_newlines);
|
||||
buff = ss.str();
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::dump_as_json", false)
|
||||
}
|
||||
inline
|
||||
bool portable_storage::load_from_json(const std::string& source)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
return json::load_from_json(source, *this);
|
||||
CATCH_ENTRY("portable_storage::load_from_json", false)
|
||||
}
|
||||
|
||||
template<class trace_policy>
|
||||
bool portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name)
|
||||
{
|
||||
return false;//TODO: don't think i ever again will use xml - ambiguous and "overtagged" format
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
bool portable_storage::store_to_binary(binarybuffer& target)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::stringstream ss;
|
||||
storage_block_header sbh = AUTO_VAL_INIT(sbh);
|
||||
sbh.m_signature_a = SWAP32LE(PORTABLE_STORAGE_SIGNATUREA);
|
||||
sbh.m_signature_b = SWAP32LE(PORTABLE_STORAGE_SIGNATUREB);
|
||||
sbh.m_ver = PORTABLE_STORAGE_FORMAT_VER;
|
||||
ss.write((const char*)&sbh, sizeof(storage_block_header));
|
||||
pack_entry_to_buff(ss, m_root);
|
||||
target = ss.str();
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::store_to_binary", false)
|
||||
}
|
||||
inline
|
||||
bool portable_storage::load_from_binary(const epee::span<const uint8_t> source)
|
||||
{
|
||||
m_root.m_entries.clear();
|
||||
if(source.size() < sizeof(storage_block_header))
|
||||
{
|
||||
LOG_ERROR("portable_storage: wrong binary format, packet size = " << source.size() << " less than expected sizeof(storage_block_header)=" << sizeof(storage_block_header));
|
||||
return false;
|
||||
}
|
||||
storage_block_header* pbuff = (storage_block_header*)source.data();
|
||||
if(pbuff->m_signature_a != SWAP32LE(PORTABLE_STORAGE_SIGNATUREA) ||
|
||||
pbuff->m_signature_b != SWAP32LE(PORTABLE_STORAGE_SIGNATUREB)
|
||||
)
|
||||
{
|
||||
LOG_ERROR("portable_storage: wrong binary format - signature mismatch");
|
||||
return false;
|
||||
}
|
||||
if(pbuff->m_ver != PORTABLE_STORAGE_FORMAT_VER)
|
||||
{
|
||||
LOG_ERROR("portable_storage: wrong binary format - unknown format ver = " << pbuff->m_ver);
|
||||
return false;
|
||||
}
|
||||
TRY_ENTRY();
|
||||
throwable_buffer_reader buf_reader(source.data()+sizeof(storage_block_header), source.size()-sizeof(storage_block_header));
|
||||
buf_reader.read(m_root);
|
||||
return true;//TODO:
|
||||
CATCH_ENTRY("portable_storage::load_from_binary", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
hparent_section = hparent_section ? hparent_section:&m_root;
|
||||
storage_entry* pentry = find_storage_entry(section_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
if(!create_if_notexist)
|
||||
return nullptr;
|
||||
return insert_new_section(section_name, hparent_section);
|
||||
}
|
||||
CHECK_AND_ASSERT(pentry , nullptr);
|
||||
//check that section_entry we find is real "CSSection"
|
||||
if(pentry->type() != typeid(section))
|
||||
{
|
||||
if(create_if_notexist)
|
||||
*pentry = storage_entry(section());//replace
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
return &boost::get<section>(*pentry);
|
||||
CATCH_ENTRY("portable_storage::open_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class to_type>
|
||||
struct get_value_visitor: boost::static_visitor<void>
|
||||
{
|
||||
@@ -149,6 +228,20 @@ namespace epee
|
||||
//CATCH_ENTRY("portable_storage::template<>get_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section)
|
||||
{
|
||||
//TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
|
||||
if(!pentry)
|
||||
return false;
|
||||
|
||||
val = *pentry;
|
||||
return true;
|
||||
//CATCH_ENTRY("portable_storage::template<>get_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class t_value>
|
||||
bool portable_storage::set_value(const std::string& value_name, t_value&& v, hsection hparent_section)
|
||||
{
|
||||
@@ -170,18 +263,40 @@ namespace epee
|
||||
CATCH_ENTRY("portable_storage::template<>set_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(psection, nullptr);
|
||||
auto it = psection->m_entries.find(pentry_name);
|
||||
if(it == psection->m_entries.end())
|
||||
return nullptr;
|
||||
|
||||
return &it->second;
|
||||
CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class entry_type>
|
||||
storage_entry* portable_storage::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, entry_type&& entry)
|
||||
{
|
||||
static_assert(std::is_rvalue_reference<entry_type&&>(), "unexpected copy of value");
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(psection, nullptr);
|
||||
CHECK_AND_ASSERT(!pentry_name.empty(), nullptr);
|
||||
auto ins_res = psection->m_entries.emplace(pentry_name, std::forward<entry_type>(entry));
|
||||
return &ins_res.first->second;
|
||||
CATCH_ENTRY("portable_storage::insert_new_entry_get_storage_entry", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
storage_entry* pse = insert_new_entry_get_storage_entry(pentry_name, psection, section());
|
||||
if(!pse) return nullptr;
|
||||
return &boost::get<section>(*pse);
|
||||
CATCH_ENTRY("portable_storage::insert_new_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class to_type>
|
||||
struct get_first_value_visitor: boost::static_visitor<bool>
|
||||
{
|
||||
@@ -235,6 +350,7 @@ namespace epee
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class t_value>
|
||||
bool portable_storage::get_next_value(harray hval_array, t_value& target)
|
||||
{
|
||||
@@ -292,5 +408,83 @@ namespace epee
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::insert_next_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
//sections
|
||||
inline
|
||||
harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
|
||||
if(!pentry)
|
||||
return nullptr;
|
||||
if(pentry->type() != typeid(array_entry))
|
||||
return nullptr;
|
||||
array_entry& ar_entry = boost::get<array_entry>(*pentry);
|
||||
if(ar_entry.type() != typeid(array_entry_t<section>))
|
||||
return nullptr;
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
|
||||
section* psec = sec_array.get_first_val();
|
||||
if(!psec)
|
||||
return nullptr;
|
||||
h_child_section = psec;
|
||||
return &ar_entry;
|
||||
CATCH_ENTRY("portable_storage::get_first_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hsec_array, false);
|
||||
if(hsec_array->type() != typeid(array_entry_t<section>))
|
||||
return false;
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
|
||||
h_child_section = sec_array.get_next_val();
|
||||
if(!h_child_section)
|
||||
return false;
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::get_next_section", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
pentry = insert_new_entry_get_storage_entry(sec_name, hparent_section, array_entry(array_entry_t<section>()));
|
||||
if(!pentry)
|
||||
return nullptr;
|
||||
}
|
||||
if(pentry->type() != typeid(array_entry))
|
||||
*pentry = storage_entry(array_entry(array_entry_t<section>()));
|
||||
|
||||
array_entry& ar_entry = boost::get<array_entry>(*pentry);
|
||||
if(ar_entry.type() != typeid(array_entry_t<section>))
|
||||
ar_entry = array_entry(array_entry_t<section>());
|
||||
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
|
||||
hinserted_childsection = &sec_array.insert_first_val(section());
|
||||
return &ar_entry;
|
||||
CATCH_ENTRY("portable_storage::insert_first_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hsec_array, false);
|
||||
CHECK_AND_ASSERT_MES(hsec_array->type() == typeid(array_entry_t<section>),
|
||||
false, "unexpected type(not 'section') in insert_next_section, type: " << hsec_array->type().name());
|
||||
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
|
||||
hinserted_childsection = &sec_array.insert_next_value(section());
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::insert_next_section", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/any.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
|
||||
#define PORTABLE_STORAGE_SIGNATUREA 0x01011101
|
||||
#define PORTABLE_STORAGE_SIGNATUREB 0x01020101 // bender's nightmare
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "misc_language.h"
|
||||
#include "misc_log_ex.h"
|
||||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_bin_utils.h"
|
||||
|
||||
@@ -43,24 +42,6 @@ namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
template<typename T>
|
||||
struct ps_min_bytes {
|
||||
static constexpr const size_t strict = 4096; // actual low bound
|
||||
};
|
||||
template<> struct ps_min_bytes<uint64_t> { static constexpr const size_t strict = 8; };
|
||||
template<> struct ps_min_bytes<int64_t> { static constexpr const size_t strict = 8; };
|
||||
template<> struct ps_min_bytes<uint32_t> { static constexpr const size_t strict = 4; };
|
||||
template<> struct ps_min_bytes<int32_t> { static constexpr const size_t strict = 4; };
|
||||
template<> struct ps_min_bytes<uint16_t> { static constexpr const size_t strict = 2; };
|
||||
template<> struct ps_min_bytes<int16_t> { static constexpr const size_t strict = 2; };
|
||||
template<> struct ps_min_bytes<uint8_t> { static constexpr const size_t strict = 1; };
|
||||
template<> struct ps_min_bytes<int8_t> { static constexpr const size_t strict = 1; };
|
||||
template<> struct ps_min_bytes<double> { static constexpr const size_t strict = 8; };
|
||||
template<> struct ps_min_bytes<bool> { static constexpr const size_t strict = 1; };
|
||||
template<> struct ps_min_bytes<std::string> { static constexpr const size_t strict = 2; };
|
||||
template<> struct ps_min_bytes<section> { static constexpr const size_t strict = 1; };
|
||||
template<> struct ps_min_bytes<array_entry> { static constexpr const size_t strict = 1; };
|
||||
|
||||
struct throwable_buffer_reader
|
||||
{
|
||||
throwable_buffer_reader(const void* ptr, size_t sz);
|
||||
@@ -80,9 +61,6 @@ namespace epee
|
||||
void read(section& sec);
|
||||
void read(std::string& str);
|
||||
void read(array_entry &ae);
|
||||
template<class t_type>
|
||||
size_t min_bytes() const;
|
||||
void set_limits(size_t objects, size_t fields, size_t strings);
|
||||
private:
|
||||
struct recursuion_limitation_guard
|
||||
{
|
||||
@@ -103,13 +81,6 @@ namespace epee
|
||||
const uint8_t* m_ptr;
|
||||
size_t m_count;
|
||||
size_t m_recursion_count;
|
||||
size_t m_objects;
|
||||
size_t m_fields;
|
||||
size_t m_strings;
|
||||
|
||||
size_t max_objects;
|
||||
size_t max_fields;
|
||||
size_t max_strings;
|
||||
};
|
||||
|
||||
inline throwable_buffer_reader::throwable_buffer_reader(const void* ptr, size_t sz)
|
||||
@@ -121,12 +92,6 @@ namespace epee
|
||||
m_ptr = (uint8_t*)ptr;
|
||||
m_count = sz;
|
||||
m_recursion_count = 0;
|
||||
m_objects = 0;
|
||||
m_fields = 0;
|
||||
m_strings = 0;
|
||||
max_objects = std::numeric_limits<size_t>::max();
|
||||
max_fields = std::numeric_limits<size_t>::max();
|
||||
max_strings = std::numeric_limits<size_t>::max();
|
||||
}
|
||||
inline
|
||||
void throwable_buffer_reader::read(void* target, size_t count)
|
||||
@@ -143,7 +108,6 @@ namespace epee
|
||||
RECURSION_LIMITATION();
|
||||
uint8_t name_len = 0;
|
||||
read(name_len);
|
||||
CHECK_AND_ASSERT_THROW_MES(name_len > 0, "Section name is missing");
|
||||
sce_name.resize(name_len);
|
||||
read((void*)sce_name.data(), name_len);
|
||||
}
|
||||
@@ -174,18 +138,7 @@ namespace epee
|
||||
//for pod types
|
||||
array_entry_t<type_name> sa;
|
||||
size_t size = read_varint();
|
||||
CHECK_AND_ASSERT_THROW_MES(size <= m_count / ps_min_bytes<type_name>::strict, "Size sanity check failed");
|
||||
if (std::is_same<type_name, section>())
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(size <= max_objects - m_objects, "Too many objects");
|
||||
m_objects += size;
|
||||
}
|
||||
else if (std::is_same<type_name, std::string>())
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(size <= max_strings - m_strings, "Too many strings");
|
||||
m_strings += size;
|
||||
}
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(size <= m_count, "Size sanity check failed");
|
||||
sa.reserve(size);
|
||||
//TODO: add some optimization here later
|
||||
while(size--)
|
||||
@@ -251,8 +204,6 @@ namespace epee
|
||||
inline storage_entry throwable_buffer_reader::read_se<std::string>()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
CHECK_AND_ASSERT_THROW_MES(m_strings + 1 <= max_strings, "Too many strings");
|
||||
m_strings += 1;
|
||||
return storage_entry(read<std::string>());
|
||||
}
|
||||
|
||||
@@ -261,8 +212,6 @@ namespace epee
|
||||
inline storage_entry throwable_buffer_reader::read_se<section>()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
CHECK_AND_ASSERT_THROW_MES(m_objects < max_objects, "Too many objects");
|
||||
++m_objects;
|
||||
section s;//use extra variable due to vs bug, line "storage_entry se(section()); " can't be compiled in visual studio
|
||||
storage_entry se(std::move(s));
|
||||
section& section_entry = boost::get<section>(se);
|
||||
@@ -314,16 +263,12 @@ namespace epee
|
||||
RECURSION_LIMITATION();
|
||||
sec.m_entries.clear();
|
||||
size_t count = read_varint();
|
||||
CHECK_AND_ASSERT_THROW_MES(count <= max_fields - m_fields, "Too many object fields");
|
||||
m_fields += count;
|
||||
while(count--)
|
||||
{
|
||||
//read section name string
|
||||
std::string sec_name;
|
||||
read_sec_name(sec_name);
|
||||
const auto insert_loc = sec.m_entries.lower_bound(sec_name);
|
||||
CHECK_AND_ASSERT_THROW_MES(insert_loc == sec.m_entries.end() || insert_loc->first != sec_name, "duplicate key: " << sec_name);
|
||||
sec.m_entries.emplace_hint(insert_loc, std::move(sec_name), load_storage_entry());
|
||||
sec.m_entries.emplace(std::move(sec_name), load_storage_entry());
|
||||
}
|
||||
}
|
||||
inline
|
||||
@@ -344,12 +289,5 @@ namespace epee
|
||||
RECURSION_LIMITATION();
|
||||
CHECK_AND_ASSERT_THROW_MES(false, "Reading array entry is not supported");
|
||||
}
|
||||
inline
|
||||
void throwable_buffer_reader::set_limits(size_t objects, size_t fields, size_t strings)
|
||||
{
|
||||
max_objects = objects;
|
||||
max_fields = fields;
|
||||
max_strings = strings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#pragma once
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "parserse_base_utils.h"
|
||||
#include "file_io_utils.h"
|
||||
|
||||
@@ -28,16 +28,12 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "byte_slice.h"
|
||||
#include "parserse_base_utils.h" /// TODO: (mj-xmr) This will be reduced in an another PR
|
||||
#include "parserse_base_utils.h"
|
||||
#include "portable_storage.h"
|
||||
#include "file_io_utils.h"
|
||||
#include "span.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
class byte_stream;
|
||||
|
||||
namespace serialization
|
||||
{
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
@@ -88,10 +84,10 @@ namespace epee
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool load_t_from_binary(t_struct& out, const epee::span<const uint8_t> binary_buff, const epee::serialization::portable_storage::limits_t *limits = NULL)
|
||||
bool load_t_from_binary(t_struct& out, const epee::span<const uint8_t> binary_buff)
|
||||
{
|
||||
portable_storage ps;
|
||||
bool rs = ps.load_from_binary(binary_buff, limits);
|
||||
bool rs = ps.load_from_binary(binary_buff);
|
||||
if(!rs)
|
||||
return false;
|
||||
|
||||
@@ -115,28 +111,19 @@ namespace epee
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool store_t_to_binary(t_struct& str_in, byte_slice& binary_buff, size_t initial_buffer_size = 8192)
|
||||
{
|
||||
portable_storage ps;
|
||||
str_in.store(ps);
|
||||
return ps.store_to_binary(binary_buff, initial_buffer_size);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
byte_slice store_t_to_binary(t_struct& str_in, size_t initial_buffer_size = 8192)
|
||||
{
|
||||
byte_slice binary_buff;
|
||||
store_t_to_binary(str_in, binary_buff, initial_buffer_size);
|
||||
return binary_buff;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool store_t_to_binary(t_struct& str_in, byte_stream& binary_buff)
|
||||
bool store_t_to_binary(t_struct& str_in, std::string& binary_buff, size_t indent = 0)
|
||||
{
|
||||
portable_storage ps;
|
||||
str_in.store(ps);
|
||||
return ps.store_to_binary(binary_buff);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
std::string store_t_to_binary(t_struct& str_in, size_t indent = 0)
|
||||
{
|
||||
std::string binary_buff;
|
||||
store_t_to_binary(str_in, binary_buff, indent);
|
||||
return binary_buff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_bin_utils.h"
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
@@ -212,7 +211,6 @@ namespace epee
|
||||
for(const section_pair& se: sec.m_entries)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(se.first.size() < std::numeric_limits<uint8_t>::max(), "storage_entry_name is too long: " << se.first.size() << ", val: " << se.first);
|
||||
CHECK_AND_ASSERT_THROW_MES(!se.first.empty(), "storage_entry_name is empty");
|
||||
uint8_t len = static_cast<uint8_t>(se.first.size());
|
||||
strm.write((const char*)&len, sizeof(len));
|
||||
strm.write(se.first.data(), size_t(len));
|
||||
|
||||
@@ -28,17 +28,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#include "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
#include "parserse_base_utils.h"
|
||||
#include "warnings.h"
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <typeinfo>
|
||||
#include <iomanip>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
|
||||
@@ -24,16 +24,33 @@
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
|
||||
|
||||
#ifndef _STRING_TOOLS_H_
|
||||
#define _STRING_TOOLS_H_
|
||||
|
||||
#include "hex.h"
|
||||
#include "mlocker.h"
|
||||
// Previously pulled in by ASIO, further cleanup still required ...
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
#include <locale>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include "misc_log_ex.h"
|
||||
#include "storages/parserse_base_utils.h"
|
||||
#include "hex.h"
|
||||
#include "memwipe.h"
|
||||
#include "mlocker.h"
|
||||
#include "span.h"
|
||||
#include "warnings.h"
|
||||
|
||||
|
||||
#ifndef OUT
|
||||
#define OUT
|
||||
@@ -57,28 +74,182 @@ namespace string_tools
|
||||
{
|
||||
return from_hex::to_string(res, s);
|
||||
}
|
||||
|
||||
std::string get_ip_string_from_int32(uint32_t ip);
|
||||
bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str);
|
||||
bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres);
|
||||
std::string num_to_string_fast(int64_t val);
|
||||
|
||||
bool compare_no_case(const std::string& str1, const std::string& str2);
|
||||
std::string& get_current_module_name();
|
||||
std::string& get_current_module_folder();
|
||||
#ifdef _WIN32
|
||||
std::string get_current_module_path();
|
||||
#endif
|
||||
bool set_module_name_and_folder(const std::string& path_to_process_);
|
||||
bool trim_left(std::string& str);
|
||||
bool trim_right(std::string& str);
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string& trim(std::string& str)
|
||||
PUSH_WARNINGS
|
||||
DISABLE_GCC_WARNING(maybe-uninitialized)
|
||||
template<class XType>
|
||||
inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id)
|
||||
{
|
||||
trim_left(str);
|
||||
trim_right(str);
|
||||
return str;
|
||||
if (std::is_integral<XType>::value && !std::numeric_limits<XType>::is_signed && !std::is_same<XType, bool>::value)
|
||||
{
|
||||
for (char c : str_id)
|
||||
{
|
||||
if (!epee::misc_utils::parse::isdigit(c))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
val = boost::lexical_cast<XType>(str_id);
|
||||
return true;
|
||||
}
|
||||
catch(const std::exception& /*e*/)
|
||||
{
|
||||
//const char* pmsg = e.what();
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
POP_WARNINGS
|
||||
//----------------------------------------------------------------------------
|
||||
template<class XType>
|
||||
inline bool xtype_to_string(const XType& val, std::string& str)
|
||||
{
|
||||
try
|
||||
{
|
||||
str = boost::lexical_cast<std::string>(val);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
std::string get_ip_string_from_int32(uint32_t ip);
|
||||
//----------------------------------------------------------------------------
|
||||
bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str);
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres)
|
||||
{
|
||||
//parse ip and address
|
||||
std::string::size_type p = addres.find(':');
|
||||
std::string ip_str, port_str;
|
||||
if(p == std::string::npos)
|
||||
{
|
||||
port = 0;
|
||||
ip_str = addres;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip_str = addres.substr(0, p);
|
||||
port_str = addres.substr(p+1, addres.size());
|
||||
}
|
||||
|
||||
if(!get_ip_int32_from_string(ip, ip_str))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(p != std::string::npos && !get_xtype_from_string(port, port_str))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline std::string num_to_string_fast(int64_t val)
|
||||
{
|
||||
/*
|
||||
char buff[30] = {0};
|
||||
i64toa_s(val, buff, sizeof(buff)-1, 10);
|
||||
return buff;*/
|
||||
return boost::lexical_cast<std::string>(val);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline std::string to_string_hex(const T &val)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "only arithmetic types");
|
||||
std::stringstream ss;
|
||||
ss << std::hex << val;
|
||||
std::string s;
|
||||
ss >> s;
|
||||
return s;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
inline bool compare_no_case(const std::string& str1, const std::string& str2)
|
||||
{
|
||||
|
||||
return !boost::iequals(str1, str2);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string& get_current_module_name()
|
||||
{
|
||||
static std::string module_name;
|
||||
return module_name;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string& get_current_module_folder()
|
||||
{
|
||||
static std::string module_folder;
|
||||
return module_folder;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
#ifdef _WIN32
|
||||
inline std::string get_current_module_path()
|
||||
{
|
||||
char pname [5000] = {0};
|
||||
GetModuleFileNameA( NULL, pname, sizeof(pname));
|
||||
pname[sizeof(pname)-1] = 0; //be happy ;)
|
||||
return pname;
|
||||
}
|
||||
#endif
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool set_module_name_and_folder(const std::string& path_to_process_)
|
||||
{
|
||||
std::string path_to_process = path_to_process_;
|
||||
#ifdef _WIN32
|
||||
path_to_process = get_current_module_path();
|
||||
#endif
|
||||
std::string::size_type a = path_to_process.rfind( '\\' );
|
||||
if(a == std::string::npos )
|
||||
{
|
||||
a = path_to_process.rfind( '/' );
|
||||
}
|
||||
if ( a != std::string::npos )
|
||||
{
|
||||
get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
|
||||
get_current_module_folder() = path_to_process.substr(0, a);
|
||||
return true;
|
||||
}else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool trim_left(std::string& str)
|
||||
{
|
||||
for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));)
|
||||
str.erase(str.begin());
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool trim_right(std::string& str)
|
||||
{
|
||||
|
||||
for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));)
|
||||
str.erase( --((it++).base()));
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string& trim(std::string& str)
|
||||
{
|
||||
|
||||
trim_left(str);
|
||||
trim_right(str);
|
||||
return str;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string trim(const std::string& str_)
|
||||
{
|
||||
@@ -87,8 +258,18 @@ namespace string_tools
|
||||
trim_right(str);
|
||||
return str;
|
||||
}
|
||||
std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false)
|
||||
{
|
||||
if (s.size() < n)
|
||||
{
|
||||
if (prepend)
|
||||
s = std::string(n - s.size(), c) + s;
|
||||
else
|
||||
s.append(n - s.size(), c);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<class t_pod_type>
|
||||
std::string pod_to_hex(const t_pod_type& s)
|
||||
@@ -115,25 +296,64 @@ namespace string_tools
|
||||
{
|
||||
return hex_to_pod(hex_str, unwrap(s));
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline std::string to_string_hex(const T &val)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "only arithmetic types");
|
||||
std::stringstream ss;
|
||||
ss << std::hex << val;
|
||||
std::string s;
|
||||
ss >> s;
|
||||
return s;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool validate_hex(uint64_t length, const std::string& str);
|
||||
std::string get_extension(const std::string& str);
|
||||
std::string cut_off_extension(const std::string& str);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string get_extension(const std::string& str)
|
||||
{
|
||||
std::string res;
|
||||
std::string::size_type pos = str.rfind('.');
|
||||
if(std::string::npos == pos)
|
||||
return res;
|
||||
|
||||
res = str.substr(pos+1, str.size()-pos);
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string cut_off_extension(const std::string& str)
|
||||
{
|
||||
std::string res;
|
||||
std::string::size_type pos = str.rfind('.');
|
||||
if(std::string::npos == pos)
|
||||
return str;
|
||||
|
||||
res = str.substr(0, pos);
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
#ifdef _WIN32
|
||||
std::wstring utf8_to_utf16(const std::string& str);
|
||||
std::string utf16_to_utf8(const std::wstring& wstr);
|
||||
inline std::wstring utf8_to_utf16(const std::string& str)
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
|
||||
if (wstr_size == 0)
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
std::wstring wstr(wstr_size, wchar_t{});
|
||||
if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
return wstr;
|
||||
}
|
||||
inline std::string utf16_to_utf8(const std::wstring& wstr)
|
||||
{
|
||||
if (wstr.empty())
|
||||
return {};
|
||||
int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
|
||||
if (str_size == 0)
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
std::string str(str_size, char{});
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _STRING_TOOLS_LEXICAL_H_
|
||||
#define _STRING_TOOLS_LEXICAL_H_
|
||||
|
||||
#include "warnings.h"
|
||||
#include "storages/parserse_base_utils.h"
|
||||
#include <boost/lexical_cast.hpp> // A heavy header, that was extracted from the rest
|
||||
|
||||
#ifndef OUT
|
||||
#define OUT
|
||||
#endif
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace string_tools
|
||||
{
|
||||
PUSH_WARNINGS
|
||||
DISABLE_GCC_WARNING(maybe-uninitialized)
|
||||
template<class XType>
|
||||
inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id)
|
||||
{
|
||||
if (std::is_integral<XType>::value && !std::numeric_limits<XType>::is_signed && !std::is_same<XType, bool>::value)
|
||||
{
|
||||
for (char c : str_id)
|
||||
{
|
||||
if (!epee::misc_utils::parse::isdigit(c))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
val = boost::lexical_cast<XType>(str_id);
|
||||
return true;
|
||||
}
|
||||
catch(const std::exception& /*e*/)
|
||||
{
|
||||
//const char* pmsg = e.what();
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
POP_WARNINGS
|
||||
|
||||
template<class XType>
|
||||
inline bool xtype_to_string(const XType& val, std::string& str)
|
||||
{
|
||||
try
|
||||
{
|
||||
str = boost::lexical_cast<std::string>(val);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //_STRING_TOOLS_LEXICAL_H_
|
||||
@@ -28,6 +28,8 @@
|
||||
#ifndef _TINY_INI_H_
|
||||
#define _TINY_INI_H_
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "string_tools.h"
|
||||
|
||||
namespace epee
|
||||
@@ -35,8 +37,20 @@ namespace epee
|
||||
namespace tiny_ini
|
||||
{
|
||||
|
||||
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res);
|
||||
inline std::string get_param_value(const std::string& param_name, const std::string& ini_entry)
|
||||
inline
|
||||
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res)
|
||||
{
|
||||
std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$";
|
||||
const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal);
|
||||
boost::smatch result;
|
||||
if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default))
|
||||
return false;
|
||||
res = result[2];
|
||||
string_tools::trim(res);
|
||||
return true;
|
||||
}
|
||||
inline
|
||||
std::string get_param_value(const std::string& param_name, const std::string& ini_entry)
|
||||
{
|
||||
std::string buff;
|
||||
get_param_value(param_name, ini_entry, buff);
|
||||
|
||||
@@ -26,25 +26,13 @@
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
set(EPEE_INCLUDE_DIR_BASE "${CMAKE_CURRENT_SOURCE_DIR}/../include")
|
||||
|
||||
# Add headers to the file list, to be able to search for them and autosave in IDEs.
|
||||
monero_find_all_headers(EPEE_HEADERS_PUBLIC "${EPEE_INCLUDE_DIR_BASE}")
|
||||
|
||||
monero_add_library(epee byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp parserse_base_utils.cpp
|
||||
add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
|
||||
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
|
||||
int-util.cpp portable_storage.cpp
|
||||
misc_language.cpp
|
||||
misc_os_dependent.cpp
|
||||
file_io_utils.cpp
|
||||
net_parse_helpers.cpp
|
||||
http_base.cpp
|
||||
tiny_ini.cpp
|
||||
${EPEE_HEADERS_PUBLIC}
|
||||
)
|
||||
int-util.cpp)
|
||||
|
||||
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
|
||||
monero_add_library(epee_readline readline_buffer.cpp)
|
||||
add_library(epee_readline STATIC readline_buffer.cpp)
|
||||
endif()
|
||||
|
||||
if(HAVE_C11)
|
||||
@@ -72,9 +60,8 @@ target_link_libraries(epee
|
||||
${Boost_CHRONO_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_THREAD_LIBRARY}
|
||||
${Boost_REGEX_LIBRARY}
|
||||
${OPENSSL_LIBRARIES}
|
||||
PRIVATE
|
||||
${OPENSSL_LIBRARIES}
|
||||
${EXTRA_LIBRARIES})
|
||||
|
||||
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
|
||||
@@ -84,9 +71,3 @@ if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
|
||||
PRIVATE
|
||||
${GNU_READLINE_LIBRARY})
|
||||
endif()
|
||||
|
||||
target_include_directories(epee
|
||||
PUBLIC
|
||||
"${EPEE_INCLUDE_DIR_BASE}"
|
||||
"${OPENSSL_INCLUDE_DIR}")
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "net/abstract_http_client.h"
|
||||
#include "net/http_base.h"
|
||||
#include "net/net_parse_helpers.h"
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
|
||||
|
||||
@@ -36,11 +36,6 @@
|
||||
#include "byte_slice.h"
|
||||
#include "byte_stream.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
const std::size_t page_size = 4096;
|
||||
}
|
||||
|
||||
namespace epee
|
||||
{
|
||||
struct byte_slice_data
|
||||
@@ -151,7 +146,7 @@ namespace epee
|
||||
: byte_slice()
|
||||
{
|
||||
std::size_t space_needed = 0;
|
||||
for (const auto& source : sources)
|
||||
for (const auto source : sources)
|
||||
space_needed += source.size();
|
||||
|
||||
if (space_needed)
|
||||
@@ -160,7 +155,7 @@ namespace epee
|
||||
span<std::uint8_t> out{reinterpret_cast<std::uint8_t*>(storage.get() + 1), space_needed};
|
||||
portion_ = {out.data(), out.size()};
|
||||
|
||||
for (const auto& source : sources)
|
||||
for (const auto source : sources)
|
||||
{
|
||||
std::memcpy(out.data(), source.data(), source.size());
|
||||
if (out.remove_prefix(source.size()) < source.size())
|
||||
@@ -178,27 +173,16 @@ namespace epee
|
||||
: byte_slice(adapt_buffer{}, std::move(buffer))
|
||||
{}
|
||||
|
||||
byte_slice::byte_slice(byte_stream&& stream, const bool shrink)
|
||||
byte_slice::byte_slice(byte_stream&& stream) noexcept
|
||||
: storage_(nullptr), portion_(stream.data(), stream.size())
|
||||
{
|
||||
if (portion_.size())
|
||||
if (stream.size())
|
||||
{
|
||||
byte_buffer buf;
|
||||
if (shrink && page_size <= stream.available())
|
||||
{
|
||||
buf = byte_buffer_resize(stream.take_buffer(), portion_.size());
|
||||
if (!buf)
|
||||
throw std::bad_alloc{};
|
||||
portion_ = {buf.get(), portion_.size()};
|
||||
}
|
||||
else // no need to shrink buffer
|
||||
buf = stream.take_buffer();
|
||||
|
||||
std::uint8_t* const data = buf.release() - sizeof(raw_byte_slice);
|
||||
std::uint8_t* const data = stream.take_buffer().release() - sizeof(raw_byte_slice);
|
||||
new (data) raw_byte_slice{};
|
||||
storage_.reset(reinterpret_cast<raw_byte_slice*>(data));
|
||||
}
|
||||
else // empty stream
|
||||
else
|
||||
portion_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,11 +34,6 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const std::size_t minimum_increase = 4096;
|
||||
}
|
||||
|
||||
namespace epee
|
||||
{
|
||||
void byte_stream::overflow(const std::size_t requested)
|
||||
@@ -51,7 +46,7 @@ namespace epee
|
||||
|
||||
const std::size_t len = size();
|
||||
const std::size_t cap = capacity();
|
||||
const std::size_t increase = std::max(std::max(need, cap), minimum_increase);
|
||||
const std::size_t increase = std::max(need, increase_size());
|
||||
|
||||
next_write_ = nullptr;
|
||||
end_ = nullptr;
|
||||
@@ -67,7 +62,8 @@ namespace epee
|
||||
byte_stream::byte_stream(byte_stream&& rhs) noexcept
|
||||
: buffer_(std::move(rhs.buffer_)),
|
||||
next_write_(rhs.next_write_),
|
||||
end_(rhs.end_)
|
||||
end_(rhs.end_),
|
||||
increase_size_(rhs.increase_size_)
|
||||
{
|
||||
rhs.next_write_ = nullptr;
|
||||
rhs.end_ = nullptr;
|
||||
@@ -80,6 +76,7 @@ namespace epee
|
||||
buffer_ = std::move(rhs.buffer_);
|
||||
next_write_ = rhs.next_write_;
|
||||
end_ = rhs.end_;
|
||||
increase_size_ = rhs.increase_size_;
|
||||
rhs.next_write_ = nullptr;
|
||||
rhs.end_ = nullptr;
|
||||
}
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "file_io_utils.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include "string_tools.h"
|
||||
#endif
|
||||
|
||||
// On Windows there is a problem with non-ASCII characters in path and file names
|
||||
// as far as support by the standard components used is concerned:
|
||||
|
||||
// The various file stream classes, e.g. std::ifstream and std::ofstream, are
|
||||
// part of the GNU C++ Library / libstdc++. On the most basic level they use the
|
||||
// fopen() call as defined / made accessible to programs compiled within MSYS2
|
||||
// by the stdio.h header file maintained by the MinGW project.
|
||||
|
||||
// The critical point: The implementation of fopen() is part of MSVCRT, the
|
||||
// Microsoft Visual C/C++ Runtime Library, and this method does NOT offer any
|
||||
// Unicode support.
|
||||
|
||||
// Monero code that would want to continue to use the normal file stream classes
|
||||
// but WITH Unicode support could therefore not solve this problem on its own,
|
||||
// but 2 different projects from 2 different maintaining groups would need changes
|
||||
// in this particular direction - something probably difficult to achieve and
|
||||
// with a long time to wait until all new versions / releases arrive.
|
||||
|
||||
// Implemented solution approach: Circumvent the problem by stopping to use std
|
||||
// file stream classes on Windows and directly use Unicode-capable WIN32 API
|
||||
// calls. Most of the code doing so is concentrated in this header file here.
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace file_io_utils
|
||||
{
|
||||
|
||||
bool is_file_exist(const std::string& path)
|
||||
{
|
||||
boost::filesystem::path p(path);
|
||||
return boost::filesystem::exists(p);
|
||||
}
|
||||
|
||||
|
||||
bool save_string_to_file(const std::string& path_to_file, const std::string& str)
|
||||
{
|
||||
#ifdef WIN32
|
||||
std::wstring wide_path;
|
||||
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
|
||||
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
DWORD bytes_written;
|
||||
DWORD bytes_to_write = (DWORD)str.size();
|
||||
BOOL result = WriteFile(file_handle, str.data(), bytes_to_write, &bytes_written, NULL);
|
||||
CloseHandle(file_handle);
|
||||
if (bytes_written != bytes_to_write)
|
||||
result = FALSE;
|
||||
return result;
|
||||
#else
|
||||
try
|
||||
{
|
||||
std::ofstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
|
||||
fstream << str;
|
||||
fstream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool get_file_time(const std::string& path_to_file, time_t& ft)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec);
|
||||
if(!ec)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool set_file_time(const std::string& path_to_file, const time_t& ft)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec);
|
||||
if(!ec)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size)
|
||||
{
|
||||
#ifdef WIN32
|
||||
std::wstring wide_path;
|
||||
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
|
||||
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
DWORD file_size = GetFileSize(file_handle, NULL);
|
||||
if ((file_size == INVALID_FILE_SIZE) || (uint64_t)file_size > (uint64_t)max_size) {
|
||||
CloseHandle(file_handle);
|
||||
return false;
|
||||
}
|
||||
target_str.resize(file_size);
|
||||
DWORD bytes_read;
|
||||
BOOL result = ReadFile(file_handle, &target_str[0], file_size, &bytes_read, NULL);
|
||||
CloseHandle(file_handle);
|
||||
if (bytes_read != file_size)
|
||||
result = FALSE;
|
||||
return result;
|
||||
#else
|
||||
try
|
||||
{
|
||||
std::ifstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
|
||||
|
||||
std::ifstream::pos_type file_size = fstream.tellg();
|
||||
|
||||
if((uint64_t)file_size > (uint64_t)max_size) // ensure a large domain for comparison, and negative -> too large
|
||||
return false;//don't go crazy
|
||||
size_t file_size_t = static_cast<size_t>(file_size);
|
||||
|
||||
target_str.resize(file_size_t);
|
||||
|
||||
fstream.seekg (0, std::ios::beg);
|
||||
fstream.read((char*)target_str.data(), target_str.size());
|
||||
fstream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool append_string_to_file(const std::string& path_to_file, const std::string& str)
|
||||
{
|
||||
// No special Windows implementation because so far not used in Monero code
|
||||
try
|
||||
{
|
||||
std::ofstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
|
||||
fstream << str;
|
||||
fstream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool get_file_size(const std::string& path_to_file, uint64_t &size)
|
||||
{
|
||||
#ifdef WIN32
|
||||
std::wstring wide_path;
|
||||
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
|
||||
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
LARGE_INTEGER file_size;
|
||||
BOOL result = GetFileSizeEx(file_handle, &file_size);
|
||||
CloseHandle(file_handle);
|
||||
if (result) {
|
||||
size = file_size.QuadPart;
|
||||
}
|
||||
return size;
|
||||
#else
|
||||
try
|
||||
{
|
||||
std::ifstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
|
||||
size = fstream.tellg();
|
||||
fstream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "net/http_base.h"
|
||||
#include "memwipe.h"
|
||||
#include "string_tools.h"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields)
|
||||
{
|
||||
fields_list::const_iterator it = fields.begin();
|
||||
for(; it != fields.end(); it++)
|
||||
if(!string_tools::compare_no_case(param_name, it->first))
|
||||
break;
|
||||
|
||||
if(it==fields.end())
|
||||
return std::string();
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri)
|
||||
{
|
||||
std::string buff = "([\\?|&])";
|
||||
buff += param_name + "=([^&]*)";
|
||||
boost::regex match_param(buff.c_str(), boost::regex::icase | boost::regex::normal);
|
||||
boost::smatch result;
|
||||
if(boost::regex_search(uri, result, match_param, boost::match_default) && result[0].matched)
|
||||
{
|
||||
return result[2];
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,25 +34,6 @@ namespace epee
|
||||
{
|
||||
namespace levin
|
||||
{
|
||||
message_writer::message_writer(const std::size_t reserve)
|
||||
: buffer()
|
||||
{
|
||||
buffer.reserve(reserve);
|
||||
buffer.put_n(0, sizeof(header));
|
||||
}
|
||||
|
||||
byte_slice message_writer::finalize(const uint32_t command, const uint32_t flags, const uint32_t return_code, const bool expect_response)
|
||||
{
|
||||
if (buffer.size() < sizeof(header))
|
||||
throw std::runtime_error{"levin_writer::finalize already called"};
|
||||
|
||||
header head = make_header(command, payload_size(), flags, expect_response);
|
||||
head.m_return_code = SWAP32LE(return_code);
|
||||
|
||||
std::memcpy(buffer.tellp() - buffer.size(), std::addressof(head), sizeof(head));
|
||||
return byte_slice{std::move(buffer)};
|
||||
}
|
||||
|
||||
bucket_head2 make_header(uint32_t command, uint64_t msg_size, uint32_t flags, bool expect_response) noexcept
|
||||
{
|
||||
bucket_head2 head = {0};
|
||||
@@ -66,6 +47,12 @@ namespace levin
|
||||
return head;
|
||||
}
|
||||
|
||||
byte_slice make_notify(int command, epee::span<const std::uint8_t> payload)
|
||||
{
|
||||
const bucket_head2 head = make_header(command, payload.size(), LEVIN_PACKET_REQUEST, false);
|
||||
return byte_slice{epee::as_byte_span(head), payload};
|
||||
}
|
||||
|
||||
byte_slice make_noise_notify(const std::size_t noise_bytes)
|
||||
{
|
||||
static constexpr const std::uint32_t flags =
|
||||
@@ -81,40 +68,46 @@ namespace levin
|
||||
return byte_slice{std::move(buffer)};
|
||||
}
|
||||
|
||||
byte_slice make_fragmented_notify(const std::size_t noise_size, const int command, message_writer message)
|
||||
byte_slice make_fragmented_notify(const byte_slice& noise_message, int command, epee::span<const std::uint8_t> payload)
|
||||
{
|
||||
const size_t noise_size = noise_message.size();
|
||||
if (noise_size < sizeof(bucket_head2) * 2)
|
||||
return nullptr;
|
||||
|
||||
if (message.buffer.size() <= noise_size)
|
||||
if (payload.size() <= noise_size - sizeof(bucket_head2))
|
||||
{
|
||||
/* The entire message can be sent at once, and the levin binary parser
|
||||
will ignore extra bytes. So just pad with zeroes and otherwise send
|
||||
a "normal", not fragmented message. */
|
||||
const size_t padding = noise_size - sizeof(bucket_head2) - payload.size();
|
||||
const span<const uint8_t> padding_bytes{noise_message.end() - padding, padding};
|
||||
|
||||
message.buffer.put_n(0, noise_size - message.buffer.size());
|
||||
return message.finalize_notify(command);
|
||||
const bucket_head2 head = make_header(command, noise_size - sizeof(bucket_head2), LEVIN_PACKET_REQUEST, false);
|
||||
return byte_slice{as_byte_span(head), payload, padding_bytes};
|
||||
}
|
||||
|
||||
// fragment message
|
||||
const byte_slice payload_bytes = message.finalize_notify(command);
|
||||
span<const std::uint8_t> payload = to_span(payload_bytes);
|
||||
|
||||
const size_t payload_space = noise_size - sizeof(bucket_head2);
|
||||
const size_t expected_fragments = ((payload.size() - 2) / payload_space) + 1;
|
||||
|
||||
byte_stream buffer{};
|
||||
buffer.reserve(expected_fragments * noise_size);
|
||||
std::string buffer{};
|
||||
buffer.reserve((expected_fragments + 1) * noise_size); // +1 here overselects for internal bucket_head2 value
|
||||
|
||||
bucket_head2 head = make_header(0, payload_space, LEVIN_PACKET_BEGIN, false);
|
||||
buffer.write(as_byte_span(head));
|
||||
bucket_head2 head = make_header(0, noise_size - sizeof(bucket_head2), LEVIN_PACKET_BEGIN, false);
|
||||
buffer.append(reinterpret_cast<const char*>(&head), sizeof(head));
|
||||
|
||||
// internal levin header is in payload already
|
||||
head.m_command = command;
|
||||
head.m_flags = LEVIN_PACKET_REQUEST;
|
||||
head.m_cb = payload.size();
|
||||
buffer.append(reinterpret_cast<const char*>(&head), sizeof(head));
|
||||
|
||||
size_t copy_size = payload.remove_prefix(payload_space);
|
||||
buffer.write(payload.data() - copy_size, copy_size);
|
||||
size_t copy_size = payload.remove_prefix(payload_space - sizeof(bucket_head2));
|
||||
buffer.append(reinterpret_cast<const char*>(payload.data()) - copy_size, copy_size);
|
||||
|
||||
head.m_command = 0;
|
||||
head.m_flags = 0;
|
||||
head.m_cb = noise_size - sizeof(bucket_head2);
|
||||
|
||||
while (!payload.empty())
|
||||
{
|
||||
copy_size = payload.remove_prefix(payload_space);
|
||||
@@ -122,12 +115,12 @@ namespace levin
|
||||
if (payload.empty())
|
||||
head.m_flags = LEVIN_PACKET_END;
|
||||
|
||||
buffer.write(as_byte_span(head));
|
||||
buffer.write(payload.data() - copy_size, copy_size);
|
||||
buffer.append(reinterpret_cast<const char*>(&head), sizeof(head));
|
||||
buffer.append(reinterpret_cast<const char*>(payload.data()) - copy_size, copy_size);
|
||||
}
|
||||
|
||||
const size_t padding = noise_size - copy_size - sizeof(bucket_head2);
|
||||
buffer.put_n(0, padding);
|
||||
buffer.append(reinterpret_cast<const char*>(noise_message.end()) - padding, padding);
|
||||
|
||||
return byte_slice{std::move(buffer)};
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "misc_language.h"
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace misc_utils
|
||||
{
|
||||
bool sleep_no_w(long ms )
|
||||
{
|
||||
boost::this_thread::sleep(
|
||||
boost::get_system_time() +
|
||||
boost::posix_time::milliseconds( std::max<long>(ms,0) ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "misc_os_dependent.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace misc_utils
|
||||
{
|
||||
// TODO: (vtnerd) This function is weird since boost::this_thread::get_id() exists but returns a different value.
|
||||
std::string get_thread_string_id()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return boost::lexical_cast<std::string>(GetCurrentThreadId());
|
||||
#elif defined(__GNUC__)
|
||||
return boost::lexical_cast<std::string>(pthread_self());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "net/net_parse_helpers.h"
|
||||
#include "net/http_base.h"
|
||||
#include "misc_log_ex.h"
|
||||
#include "reg_exp_definer.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
|
||||
static bool parse_uri_query(const std::string& query, std::list<std::pair<std::string, std::string> >& params)
|
||||
{
|
||||
enum state
|
||||
{
|
||||
st_param_name,
|
||||
st_param_val
|
||||
};
|
||||
state st = st_param_name;
|
||||
std::string::const_iterator start_it = query.begin();
|
||||
std::pair<std::string, std::string> e;
|
||||
for(std::string::const_iterator it = query.begin(); it != query.end(); it++)
|
||||
{
|
||||
switch(st)
|
||||
{
|
||||
case st_param_name:
|
||||
if(*it == '=')
|
||||
{
|
||||
e.first.assign(start_it, it);
|
||||
start_it = it;++start_it;
|
||||
st = st_param_val;
|
||||
}
|
||||
break;
|
||||
case st_param_val:
|
||||
if(*it == '&')
|
||||
{
|
||||
e.second.assign(start_it, it);
|
||||
start_it = it;++start_it;
|
||||
params.push_back(e);
|
||||
e.first.clear();e.second.clear();
|
||||
st = st_param_name;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unknown state " << (int)st);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(st == st_param_name)
|
||||
{
|
||||
if(start_it != query.end())
|
||||
{
|
||||
e.first.assign(start_it, query.end());
|
||||
params.push_back(e);
|
||||
}
|
||||
}else
|
||||
{
|
||||
if(start_it != query.end())
|
||||
e.second.assign(start_it, query.end());
|
||||
|
||||
if(e.first.size())
|
||||
params.push_back(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_uri(const std::string uri, http::uri_content& content)
|
||||
{
|
||||
|
||||
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
|
||||
content.m_query_params.clear();
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
|
||||
|
||||
boost::smatch result;
|
||||
if(!(boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched))
|
||||
{
|
||||
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri);
|
||||
content.m_path = uri;
|
||||
return true;
|
||||
}
|
||||
if(result[1].matched)
|
||||
{
|
||||
content.m_path = result[1];
|
||||
}
|
||||
if(result[3].matched)
|
||||
{
|
||||
content.m_query = result[3];
|
||||
}
|
||||
if(result[5].matched)
|
||||
{
|
||||
content.m_fragment = result[5];
|
||||
}
|
||||
if(content.m_query.size())
|
||||
{
|
||||
parse_uri_query(content.m_query, content.m_query_params);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_url_ipv6(const std::string url_str, http::url_content& content)
|
||||
{
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
|
||||
// 12 3 4 5 6 7
|
||||
|
||||
content.port = 0;
|
||||
boost::smatch result;
|
||||
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
|
||||
{
|
||||
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
|
||||
//content.m_path = uri;
|
||||
return false;
|
||||
}
|
||||
if(result[2].matched)
|
||||
{
|
||||
content.schema = result[2];
|
||||
}
|
||||
if(result[4].matched)
|
||||
{
|
||||
content.host = result[4];
|
||||
}
|
||||
else // if host not matched, matching should be considered failed
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(result[6].matched)
|
||||
{
|
||||
content.port = boost::lexical_cast<uint64_t>(result[6]);
|
||||
}
|
||||
if(result[7].matched)
|
||||
{
|
||||
content.uri = result[7];
|
||||
return parse_uri(result[7], content.m_uri_content);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_url(const std::string url_str, http::url_content& content)
|
||||
{
|
||||
|
||||
if (parse_url_ipv6(url_str, content)) return true;
|
||||
|
||||
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
|
||||
//STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
|
||||
// 12 34 5 6 7
|
||||
content.port = 0;
|
||||
boost::smatch result;
|
||||
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
|
||||
{
|
||||
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
|
||||
//content.m_path = uri;
|
||||
return true;
|
||||
}
|
||||
if(result[2].matched)
|
||||
{
|
||||
content.schema = result[2];
|
||||
}
|
||||
if(result[4].matched)
|
||||
{
|
||||
content.host = result[4];
|
||||
}
|
||||
if(result[6].matched)
|
||||
{
|
||||
content.port = boost::lexical_cast<uint64_t>(result[6]);
|
||||
}
|
||||
if(result[7].matched)
|
||||
{
|
||||
content.uri = result[7];
|
||||
return parse_uri(result[7], content.m_uri_content);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,6 @@
|
||||
#include <string.h>
|
||||
#include <thread>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/cerrno.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/pem.h>
|
||||
@@ -475,7 +473,6 @@ bool ssl_options_t::has_fingerprint(boost::asio::ssl::verify_context &ctx) const
|
||||
bool ssl_options_t::handshake(
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket,
|
||||
boost::asio::ssl::stream_base::handshake_type type,
|
||||
boost::asio::const_buffer buffer,
|
||||
const std::string& host,
|
||||
std::chrono::milliseconds timeout) const
|
||||
{
|
||||
@@ -533,7 +530,7 @@ bool ssl_options_t::handshake(
|
||||
});
|
||||
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
socket.async_handshake(type, boost::asio::buffer(buffer), boost::lambda::var(ec) = boost::lambda::_1);
|
||||
socket.async_handshake(type, boost::lambda::var(ec) = boost::lambda::_1);
|
||||
if (io_service.stopped())
|
||||
{
|
||||
io_service.reset();
|
||||
@@ -569,51 +566,6 @@ bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s)
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::system::error_code store_ssl_keys(boost::asio::ssl::context& ssl, const boost::filesystem::path& base)
|
||||
{
|
||||
EVP_PKEY* ssl_key = nullptr;
|
||||
X509* ssl_cert = nullptr;
|
||||
const auto ctx = ssl.native_handle();
|
||||
CHECK_AND_ASSERT_MES(ctx, boost::system::error_code(EINVAL, boost::system::system_category()), "Context is null");
|
||||
CHECK_AND_ASSERT_MES(base.has_filename(), boost::system::error_code(EINVAL, boost::system::system_category()), "Need filename");
|
||||
if (!(ssl_key = SSL_CTX_get0_privatekey(ctx)) || !(ssl_cert = SSL_CTX_get0_certificate(ctx)))
|
||||
return {EINVAL, boost::system::system_category()};
|
||||
|
||||
using file_closer = int(std::FILE*);
|
||||
boost::system::error_code error{};
|
||||
std::unique_ptr<std::FILE, file_closer*> file{nullptr, std::fclose};
|
||||
|
||||
// write key file unencrypted
|
||||
{
|
||||
const boost::filesystem::path key_file{base.string() + ".key"};
|
||||
file.reset(std::fopen(key_file.string().c_str(), "wb"));
|
||||
if (!file)
|
||||
return {errno, boost::system::system_category()};
|
||||
boost::filesystem::permissions(key_file, boost::filesystem::owner_read, error);
|
||||
if (error)
|
||||
return error;
|
||||
if (!PEM_write_PrivateKey(file.get(), ssl_key, nullptr, nullptr, 0, nullptr, nullptr))
|
||||
return boost::asio::error::ssl_errors(ERR_get_error());
|
||||
if (std::fclose(file.release()) != 0)
|
||||
return {errno, boost::system::system_category()};
|
||||
}
|
||||
|
||||
// write certificate file in standard SSL X.509 unencrypted
|
||||
const boost::filesystem::path cert_file{base.string() + ".crt"};
|
||||
file.reset(std::fopen(cert_file.string().c_str(), "wb"));
|
||||
if (!file)
|
||||
return {errno, boost::system::system_category()};
|
||||
const auto cert_perms = (boost::filesystem::owner_read | boost::filesystem::group_read | boost::filesystem::others_read);
|
||||
boost::filesystem::permissions(cert_file, cert_perms, error);
|
||||
if (error)
|
||||
return error;
|
||||
if (!PEM_write_X509(file.get(), ssl_cert))
|
||||
return boost::asio::error::ssl_errors(ERR_get_error());
|
||||
if (std::fclose(file.release()) != 0)
|
||||
return {errno, boost::system::system_category()};
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -6,17 +6,6 @@
|
||||
#include "string_tools.h"
|
||||
#include "net/local_ip.h"
|
||||
|
||||
static inline uint32_t make_address_v4_from_v6(const boost::asio::ip::address_v6& a)
|
||||
{
|
||||
const auto &bytes = a.to_bytes();
|
||||
uint32_t v4 = 0;
|
||||
v4 = (v4 << 8) | bytes[12];
|
||||
v4 = (v4 << 8) | bytes[13];
|
||||
v4 = (v4 << 8) | bytes[14];
|
||||
v4 = (v4 << 8) | bytes[15];
|
||||
return htonl(v4);
|
||||
}
|
||||
|
||||
namespace epee { namespace net_utils
|
||||
{
|
||||
bool ipv4_network_address::equal(const ipv4_network_address& other) const noexcept
|
||||
@@ -94,28 +83,8 @@ namespace epee { namespace net_utils
|
||||
network_address::interface const* const other_self = other.self.get();
|
||||
if (self_ == other_self) return true;
|
||||
if (!self_ || !other_self) return false;
|
||||
if (typeid(*self_) == typeid(*other_self))
|
||||
return self_->is_same_host(*other_self);
|
||||
const auto this_id = get_type_id();
|
||||
if (this_id == ipv4_network_address::get_type_id() && other.get_type_id() == ipv6_network_address::get_type_id())
|
||||
{
|
||||
const boost::asio::ip::address_v6 &actual_ip = other.as<const epee::net_utils::ipv6_network_address>().ip();
|
||||
if (actual_ip.is_v4_mapped())
|
||||
{
|
||||
const uint32_t v4ip = make_address_v4_from_v6(actual_ip);
|
||||
return is_same_host(ipv4_network_address(v4ip, 0));
|
||||
}
|
||||
}
|
||||
else if (this_id == ipv6_network_address::get_type_id() && other.get_type_id() == ipv4_network_address::get_type_id())
|
||||
{
|
||||
const boost::asio::ip::address_v6 &actual_ip = this->as<const epee::net_utils::ipv6_network_address>().ip();
|
||||
if (actual_ip.is_v4_mapped())
|
||||
{
|
||||
const uint32_t v4ip = make_address_v4_from_v6(actual_ip);
|
||||
return other.is_same_host(ipv4_network_address(v4ip, 0));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (typeid(*self_) != typeid(*other_self)) return false;
|
||||
return self_->is_same_host(*other_self);
|
||||
}
|
||||
|
||||
std::string print_connection_context(const connection_context_base& ctx)
|
||||
|
||||
@@ -1,282 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "storages/parserse_base_utils.h"
|
||||
|
||||
#include "misc_log_ex.h"
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace misc_utils
|
||||
{
|
||||
namespace parse
|
||||
{
|
||||
std::string transform_to_escape_sequence(const std::string& src)
|
||||
{
|
||||
static const char escaped[] = "\b\f\n\r\t\v\"\\/";
|
||||
std::string::const_iterator it = std::find_first_of(src.begin(), src.end(), escaped, escaped + sizeof(escaped));
|
||||
if (it == src.end())
|
||||
return src;
|
||||
|
||||
std::string res;
|
||||
res.reserve(2 * src.size());
|
||||
res.assign(src.begin(), it);
|
||||
for(; it!=src.end(); ++it)
|
||||
{
|
||||
switch(*it)
|
||||
{
|
||||
case '\b': //Backspace (ascii code 08)
|
||||
res+="\\b"; break;
|
||||
case '\f': //Form feed (ascii code 0C)
|
||||
res+="\\f"; break;
|
||||
case '\n': //New line
|
||||
res+="\\n"; break;
|
||||
case '\r': //Carriage return
|
||||
res+="\\r"; break;
|
||||
case '\t': //Tab
|
||||
res+="\\t"; break;
|
||||
case '\v': //Vertical tab
|
||||
res+="\\v"; break;
|
||||
//case '\'': //Apostrophe or single quote
|
||||
// res+="\\'"; break;
|
||||
case '"': //Double quote
|
||||
res+="\\\""; break;
|
||||
case '\\': //Backslash caracter
|
||||
res+="\\\\"; break;
|
||||
case '/': //Backslash caracter
|
||||
res+="\\/"; break;
|
||||
default:
|
||||
res.push_back(*it);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/*
|
||||
|
||||
\b Backspace (ascii code 08)
|
||||
\f Form feed (ascii code 0C)
|
||||
\n New line
|
||||
\r Carriage return
|
||||
\t Tab
|
||||
\v Vertical tab
|
||||
\' Apostrophe or single quote
|
||||
\" Double quote
|
||||
\\ Backslash character
|
||||
|
||||
*/
|
||||
void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
bool escape_mode = false;
|
||||
std::string::const_iterator it = star_end_string;
|
||||
++it;
|
||||
std::string::const_iterator fi = it;
|
||||
while (fi != buf_end && ((lut[(uint8_t)*fi] & 32)) == 0)
|
||||
++fi;
|
||||
val.assign(it, fi);
|
||||
it = fi;
|
||||
for(;it != buf_end;it++)
|
||||
{
|
||||
if(escape_mode/*prev_ch == '\\'*/)
|
||||
{
|
||||
switch(*it)
|
||||
{
|
||||
case 'b': //Backspace (ascii code 08)
|
||||
val.push_back(0x08);break;
|
||||
case 'f': //Form feed (ascii code 0C)
|
||||
val.push_back(0x0C);break;
|
||||
case 'n': //New line
|
||||
val.push_back('\n');break;
|
||||
case 'r': //Carriage return
|
||||
val.push_back('\r');break;
|
||||
case 't': //Tab
|
||||
val.push_back('\t');break;
|
||||
case 'v': //Vertical tab
|
||||
val.push_back('\v');break;
|
||||
case '\'': //Apostrophe or single quote
|
||||
val.push_back('\'');break;
|
||||
case '"': //Double quote
|
||||
val.push_back('"');break;
|
||||
case '\\': //Backslash character
|
||||
val.push_back('\\');break;
|
||||
case '/': //Slash character
|
||||
val.push_back('/');break;
|
||||
case 'u': //Unicode code point
|
||||
if (buf_end - it < 4)
|
||||
{
|
||||
ASSERT_MES_AND_THROW("Invalid Unicode escape sequence");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dst = 0;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
const unsigned char tmp = isx[(unsigned char)*++it];
|
||||
CHECK_AND_ASSERT_THROW_MES(tmp != 0xff, "Bad Unicode encoding");
|
||||
dst = dst << 4 | tmp;
|
||||
}
|
||||
// encode as UTF-8
|
||||
if (dst <= 0x7f)
|
||||
{
|
||||
val.push_back(dst);
|
||||
}
|
||||
else if (dst <= 0x7ff)
|
||||
{
|
||||
val.push_back(0xc0 | (dst >> 6));
|
||||
val.push_back(0x80 | (dst & 0x3f));
|
||||
}
|
||||
else if (dst <= 0xffff)
|
||||
{
|
||||
val.push_back(0xe0 | (dst >> 12));
|
||||
val.push_back(0x80 | ((dst >> 6) & 0x3f));
|
||||
val.push_back(0x80 | (dst & 0x3f));
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_MES_AND_THROW("Unicode code point is out or range");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
val.push_back(*it);
|
||||
LOG_PRINT_L0("Unknown escape sequence :\"\\" << *it << "\"");
|
||||
}
|
||||
escape_mode = false;
|
||||
}else if(*it == '"')
|
||||
{
|
||||
star_end_string = it;
|
||||
return;
|
||||
}else if(*it == '\\')
|
||||
{
|
||||
escape_mode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
val.push_back(*it);
|
||||
}
|
||||
}
|
||||
ASSERT_MES_AND_THROW("Failed to match string in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
void match_number2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val, bool& is_float_val, bool& is_signed_val)
|
||||
{
|
||||
val.clear();
|
||||
uint8_t float_flag = 0;
|
||||
is_signed_val = false;
|
||||
size_t chars = 0;
|
||||
std::string::const_iterator it = star_end_string;
|
||||
if (it != buf_end && *it == '-')
|
||||
{
|
||||
is_signed_val = true;
|
||||
++chars;
|
||||
++it;
|
||||
}
|
||||
for(;it != buf_end;it++)
|
||||
{
|
||||
const uint8_t flags = lut[(uint8_t)*it];
|
||||
if (flags & 16)
|
||||
{
|
||||
float_flag |= flags;
|
||||
++chars;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = boost::string_ref(&*star_end_string, chars);
|
||||
if(val.size())
|
||||
{
|
||||
star_end_string = --it;
|
||||
is_float_val = !!(float_flag & 2);
|
||||
return;
|
||||
}
|
||||
else
|
||||
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
}
|
||||
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
void match_word2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
|
||||
{
|
||||
val.clear();
|
||||
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if (!(lut[(uint8_t)*it] & 4))
|
||||
{
|
||||
val = boost::string_ref(&*star_end_string, std::distance(star_end_string, it));
|
||||
if(val.size())
|
||||
{
|
||||
star_end_string = --it;
|
||||
return;
|
||||
}else
|
||||
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
}
|
||||
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
bool match_word_with_extrasymb(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
val.clear();
|
||||
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if(!isalnum(*it) && *it != '-' && *it != '_')
|
||||
{
|
||||
val.assign(star_end_string, it);
|
||||
if(val.size())
|
||||
{
|
||||
star_end_string = --it;
|
||||
return true;
|
||||
}else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool match_word_til_equal_mark(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string::const_iterator& word_end)
|
||||
{
|
||||
word_end = star_end_string;
|
||||
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if(isspace(*it))
|
||||
{
|
||||
|
||||
continue;
|
||||
}else if( *it == '=' )
|
||||
{
|
||||
star_end_string = it;
|
||||
word_end = it;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "byte_slice.h"
|
||||
#include "byte_stream.h"
|
||||
#include "misc_log_ex.h"
|
||||
#include "span.h"
|
||||
#include "storages/portable_storage.h"
|
||||
#include "storages/portable_storage_to_json.h"
|
||||
#include "storages/portable_storage_from_json.h"
|
||||
#include "storages/portable_storage_to_bin.h"
|
||||
#include "storages/portable_storage_from_bin.h"
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
bool portable_storage::store_to_binary(byte_slice& target, const std::size_t initial_buffer_size)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
byte_stream ss;
|
||||
ss.reserve(initial_buffer_size);
|
||||
store_to_binary(ss);
|
||||
target = epee::byte_slice{std::move(ss)};
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::store_to_binary", false);
|
||||
}
|
||||
|
||||
bool portable_storage::store_to_binary(byte_stream& ss)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
storage_block_header sbh{};
|
||||
sbh.m_signature_a = SWAP32LE(PORTABLE_STORAGE_SIGNATUREA);
|
||||
sbh.m_signature_b = SWAP32LE(PORTABLE_STORAGE_SIGNATUREB);
|
||||
sbh.m_ver = PORTABLE_STORAGE_FORMAT_VER;
|
||||
ss.write(epee::as_byte_span(sbh));
|
||||
pack_entry_to_buff(ss, m_root);
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::store_to_binary", false);
|
||||
}
|
||||
|
||||
bool portable_storage::dump_as_json(std::string& buff, size_t indent, bool insert_newlines)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::stringstream ss;
|
||||
epee::serialization::dump_as_json(ss, m_root, indent, insert_newlines);
|
||||
buff = ss.str();
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::dump_as_json", false)
|
||||
}
|
||||
|
||||
bool portable_storage::load_from_json(const std::string& source)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
return json::load_from_json(source, *this);
|
||||
CATCH_ENTRY("portable_storage::load_from_json", false)
|
||||
}
|
||||
|
||||
bool portable_storage::load_from_binary(const epee::span<const uint8_t> source, const limits_t *limits)
|
||||
{
|
||||
m_root.m_entries.clear();
|
||||
if(source.size() < sizeof(storage_block_header))
|
||||
{
|
||||
LOG_ERROR("portable_storage: wrong binary format, packet size = " << source.size() << " less than expected sizeof(storage_block_header)=" << sizeof(storage_block_header));
|
||||
return false;
|
||||
}
|
||||
storage_block_header* pbuff = (storage_block_header*)source.data();
|
||||
if(pbuff->m_signature_a != SWAP32LE(PORTABLE_STORAGE_SIGNATUREA) ||
|
||||
pbuff->m_signature_b != SWAP32LE(PORTABLE_STORAGE_SIGNATUREB)
|
||||
)
|
||||
{
|
||||
LOG_ERROR("portable_storage: wrong binary format - signature mismatch");
|
||||
return false;
|
||||
}
|
||||
if(pbuff->m_ver != PORTABLE_STORAGE_FORMAT_VER)
|
||||
{
|
||||
LOG_ERROR("portable_storage: wrong binary format - unknown format ver = " << pbuff->m_ver);
|
||||
return false;
|
||||
}
|
||||
TRY_ENTRY();
|
||||
throwable_buffer_reader buf_reader(source.data()+sizeof(storage_block_header), source.size()-sizeof(storage_block_header));
|
||||
if (limits)
|
||||
buf_reader.set_limits(limits->n_objects, limits->n_fields, limits->n_strings);
|
||||
buf_reader.read(m_root);
|
||||
return true;//TODO:
|
||||
CATCH_ENTRY("portable_storage::load_from_binary", false);
|
||||
}
|
||||
|
||||
hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
hparent_section = hparent_section ? hparent_section:&m_root;
|
||||
storage_entry* pentry = find_storage_entry(section_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
if(!create_if_notexist)
|
||||
return nullptr;
|
||||
return insert_new_section(section_name, hparent_section);
|
||||
}
|
||||
CHECK_AND_ASSERT(pentry , nullptr);
|
||||
//check that section_entry we find is real "CSSection"
|
||||
if(pentry->type() != typeid(section))
|
||||
{
|
||||
if(create_if_notexist)
|
||||
*pentry = storage_entry(section());//replace
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
return &boost::get<section>(*pentry);
|
||||
CATCH_ENTRY("portable_storage::open_section", nullptr);
|
||||
}
|
||||
|
||||
bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section)
|
||||
{
|
||||
//TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
|
||||
if(!pentry)
|
||||
return false;
|
||||
|
||||
val = *pentry;
|
||||
return true;
|
||||
//CATCH_ENTRY("portable_storage::template<>get_value", false);
|
||||
}
|
||||
|
||||
storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(psection, nullptr);
|
||||
auto it = psection->m_entries.find(pentry_name);
|
||||
if(it == psection->m_entries.end())
|
||||
return nullptr;
|
||||
|
||||
return &it->second;
|
||||
CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
|
||||
}
|
||||
|
||||
hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
storage_entry* pse = insert_new_entry_get_storage_entry(pentry_name, psection, section());
|
||||
if(!pse) return nullptr;
|
||||
return &boost::get<section>(*pse);
|
||||
CATCH_ENTRY("portable_storage::insert_new_section", nullptr);
|
||||
}
|
||||
|
||||
harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
|
||||
if(!pentry)
|
||||
return nullptr;
|
||||
if(pentry->type() != typeid(array_entry))
|
||||
return nullptr;
|
||||
array_entry& ar_entry = boost::get<array_entry>(*pentry);
|
||||
if(ar_entry.type() != typeid(array_entry_t<section>))
|
||||
return nullptr;
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
|
||||
section* psec = sec_array.get_first_val();
|
||||
if(!psec)
|
||||
return nullptr;
|
||||
h_child_section = psec;
|
||||
return &ar_entry;
|
||||
CATCH_ENTRY("portable_storage::get_first_section", nullptr);
|
||||
}
|
||||
|
||||
bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hsec_array, false);
|
||||
if(hsec_array->type() != typeid(array_entry_t<section>))
|
||||
return false;
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
|
||||
h_child_section = sec_array.get_next_val();
|
||||
if(!h_child_section)
|
||||
return false;
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::get_next_section", false);
|
||||
}
|
||||
|
||||
harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
pentry = insert_new_entry_get_storage_entry(sec_name, hparent_section, array_entry(array_entry_t<section>()));
|
||||
if(!pentry)
|
||||
return nullptr;
|
||||
}
|
||||
if(pentry->type() != typeid(array_entry))
|
||||
*pentry = storage_entry(array_entry(array_entry_t<section>()));
|
||||
|
||||
array_entry& ar_entry = boost::get<array_entry>(*pentry);
|
||||
if(ar_entry.type() != typeid(array_entry_t<section>))
|
||||
ar_entry = array_entry(array_entry_t<section>());
|
||||
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
|
||||
hinserted_childsection = &sec_array.insert_first_val(section());
|
||||
return &ar_entry;
|
||||
CATCH_ENTRY("portable_storage::insert_first_section", nullptr);
|
||||
}
|
||||
|
||||
bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hsec_array, false);
|
||||
CHECK_AND_ASSERT_MES(hsec_array->type() == typeid(array_entry_t<section>),
|
||||
false, "unexpected type(not 'section') in insert_next_section, type: " << hsec_array->type().name());
|
||||
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
|
||||
hinserted_childsection = &sec_array.insert_next_value(section());
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::insert_next_section", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <boost/thread/lock_guard.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
static bool same_as_last_line(const std::string&);
|
||||
static void install_line_handler();
|
||||
static void remove_line_handler();
|
||||
|
||||
@@ -52,7 +51,6 @@ rdln::readline_buffer::readline_buffer()
|
||||
|
||||
void rdln::readline_buffer::start()
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(sync_mutex);
|
||||
if(m_cout_buf != NULL)
|
||||
return;
|
||||
m_cout_buf = std::cout.rdbuf();
|
||||
@@ -62,7 +60,6 @@ void rdln::readline_buffer::start()
|
||||
|
||||
void rdln::readline_buffer::stop()
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(sync_mutex);
|
||||
if(m_cout_buf == NULL)
|
||||
return;
|
||||
std::cout.rdbuf(m_cout_buf);
|
||||
@@ -91,9 +88,9 @@ rdln::linestatus rdln::readline_buffer::get_line(std::string& line) const
|
||||
|
||||
void rdln::readline_buffer::set_prompt(const std::string& prompt)
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(sync_mutex);
|
||||
if(m_cout_buf == NULL)
|
||||
return;
|
||||
boost::lock_guard<boost::mutex> lock(sync_mutex);
|
||||
rl_set_prompt(std::string(m_prompt_length, ' ').c_str());
|
||||
rl_redisplay();
|
||||
rl_set_prompt(prompt.c_str());
|
||||
@@ -116,12 +113,6 @@ const std::vector<std::string>& rdln::readline_buffer::get_completions()
|
||||
int rdln::readline_buffer::sync()
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(sync_mutex);
|
||||
|
||||
if (m_cout_buf == nullptr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if RL_READLINE_VERSION < 0x0700
|
||||
char lbuf[2] = {0,0};
|
||||
char *line = NULL;
|
||||
@@ -176,11 +167,8 @@ static void handle_line(char* line)
|
||||
boost::trim_right(test_line);
|
||||
if(!test_line.empty())
|
||||
{
|
||||
if (!same_as_last_line(test_line))
|
||||
{
|
||||
add_history(test_line.c_str());
|
||||
history_set_pos(history_length);
|
||||
}
|
||||
add_history(test_line.c_str());
|
||||
history_set_pos(history_length);
|
||||
if (test_line == "exit" || test_line == "q")
|
||||
exit = true;
|
||||
}
|
||||
@@ -196,16 +184,6 @@ static void handle_line(char* line)
|
||||
return;
|
||||
}
|
||||
|
||||
// same_as_last_line returns true, if the last line in the history is
|
||||
// equal to test_line.
|
||||
static bool same_as_last_line(const std::string& test_line)
|
||||
{
|
||||
// Note that state->offset == state->length, when a new line was entered.
|
||||
HISTORY_STATE* state = history_get_history_state();
|
||||
return state->length > 0
|
||||
&& test_line.compare(state->entries[state->length-1]->line) == 0;
|
||||
}
|
||||
|
||||
static char* completion_matches(const char* text, int state)
|
||||
{
|
||||
static size_t list_index;
|
||||
|
||||
@@ -25,29 +25,6 @@
|
||||
//
|
||||
|
||||
#include "string_tools.h"
|
||||
#include "string_tools_lexical.h"
|
||||
|
||||
|
||||
// Previously pulled in by ASIO, further cleanup still required ...
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <locale>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include "misc_log_ex.h"
|
||||
#include "storages/parserse_base_utils.h"
|
||||
#include "hex.h"
|
||||
#include "memwipe.h"
|
||||
#include "mlocker.h"
|
||||
#include "span.h"
|
||||
#include "warnings.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -91,180 +68,6 @@ namespace string_tools
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres)
|
||||
{
|
||||
//parse ip and address
|
||||
std::string::size_type p = addres.find(':');
|
||||
std::string ip_str, port_str;
|
||||
if(p == std::string::npos)
|
||||
{
|
||||
port = 0;
|
||||
ip_str = addres;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip_str = addres.substr(0, p);
|
||||
port_str = addres.substr(p+1, addres.size());
|
||||
}
|
||||
|
||||
if(!get_ip_int32_from_string(ip, ip_str))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(p != std::string::npos && !get_xtype_from_string(port, port_str))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string num_to_string_fast(int64_t val)
|
||||
{
|
||||
/*
|
||||
char buff[30] = {0};
|
||||
i64toa_s(val, buff, sizeof(buff)-1, 10);
|
||||
return buff;*/
|
||||
return boost::lexical_cast<std::string>(val);
|
||||
}
|
||||
|
||||
|
||||
bool compare_no_case(const std::string& str1, const std::string& str2)
|
||||
{
|
||||
|
||||
return !boost::iequals(str1, str2);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
std::string& get_current_module_name()
|
||||
{
|
||||
static std::string module_name;
|
||||
return module_name;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
std::string& get_current_module_folder()
|
||||
{
|
||||
static std::string module_folder;
|
||||
return module_folder;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string get_current_module_path()
|
||||
{
|
||||
char pname [5000] = {0};
|
||||
GetModuleFileNameA( NULL, pname, sizeof(pname));
|
||||
pname[sizeof(pname)-1] = 0; //be happy ;)
|
||||
return pname;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool set_module_name_and_folder(const std::string& path_to_process_)
|
||||
{
|
||||
std::string path_to_process = path_to_process_;
|
||||
#ifdef _WIN32
|
||||
path_to_process = get_current_module_path();
|
||||
#endif
|
||||
std::string::size_type a = path_to_process.rfind( '\\' );
|
||||
if(a == std::string::npos )
|
||||
{
|
||||
a = path_to_process.rfind( '/' );
|
||||
}
|
||||
if ( a != std::string::npos )
|
||||
{
|
||||
get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
|
||||
get_current_module_folder() = path_to_process.substr(0, a);
|
||||
return true;
|
||||
}else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool trim_left(std::string& str)
|
||||
{
|
||||
for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));)
|
||||
str.erase(str.begin());
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
bool trim_right(std::string& str)
|
||||
{
|
||||
|
||||
for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));)
|
||||
str.erase( --((it++).base()));
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
std::string pad_string(std::string s, size_t n, char c, bool prepend)
|
||||
{
|
||||
if (s.size() < n)
|
||||
{
|
||||
if (prepend)
|
||||
s = std::string(n - s.size(), c) + s;
|
||||
else
|
||||
s.append(n - s.size(), c);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string get_extension(const std::string& str)
|
||||
{
|
||||
std::string res;
|
||||
std::string::size_type pos = str.rfind('.');
|
||||
if(std::string::npos == pos)
|
||||
return res;
|
||||
|
||||
res = str.substr(pos+1, str.size()-pos);
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cut_off_extension(const std::string& str)
|
||||
{
|
||||
std::string res;
|
||||
std::string::size_type pos = str.rfind('.');
|
||||
if(std::string::npos == pos)
|
||||
return str;
|
||||
|
||||
res = str.substr(0, pos);
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
#ifdef _WIN32
|
||||
std::wstring utf8_to_utf16(const std::string& str)
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
|
||||
if (wstr_size == 0)
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
std::wstring wstr(wstr_size, wchar_t{});
|
||||
if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
return wstr;
|
||||
}
|
||||
std::string utf16_to_utf8(const std::wstring& wstr)
|
||||
{
|
||||
if (wstr.empty())
|
||||
return {};
|
||||
int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
|
||||
if (str_size == 0)
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
std::string str(str_size, char{});
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "string_tools.h"
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace tiny_ini
|
||||
{
|
||||
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res)
|
||||
{
|
||||
std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$";
|
||||
const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal);
|
||||
boost::smatch result;
|
||||
if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default))
|
||||
return false;
|
||||
res = result[2];
|
||||
string_tools::trim(res);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ then
|
||||
exit 1
|
||||
fi
|
||||
case "$type" in
|
||||
block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin|bulletproof|utf8) ;;
|
||||
*) echo "usage: $0 block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin|bulletproof|utf8"; exit 1 ;;
|
||||
block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin|bulletproof) ;;
|
||||
*) echo "usage: $0 block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin|bulletproof"; exit 1 ;;
|
||||
esac
|
||||
|
||||
if test -d "fuzz-out/$type"
|
||||
|
||||
@@ -36,10 +36,6 @@ This guide explains how to set up the environment, and how to start the builds.
|
||||
|
||||
You need to create a new user called `gitianuser` and be logged in as that user. The user needs `sudo` access.
|
||||
|
||||
```bash
|
||||
sudo adduser gitianuser
|
||||
sudo usermod -aG sudo gitianuser
|
||||
```
|
||||
|
||||
LXC
|
||||
---
|
||||
@@ -87,7 +83,7 @@ Docker
|
||||
Prepare for building with docker:
|
||||
|
||||
```bash
|
||||
sudo bash -c 'apt-get update && apt-get upgrade -y && apt-get install git curl docker.io'
|
||||
sudo apt-get install git make curl docker.io
|
||||
```
|
||||
|
||||
Consider adding `gitianuser` to the `docker` group after reading about [the security implications](https://docs.docker.com/v17.09/engine/installation/linux/linux-postinstall/):
|
||||
@@ -100,12 +96,13 @@ sudo usermod -aG docker gitianuser
|
||||
Optionally add yourself to the docker group. Note that this will give docker root access to your system.
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker $USER
|
||||
sudo usermod -aG docker gitianuser
|
||||
```
|
||||
|
||||
Manual Building
|
||||
-------------------
|
||||
|
||||
The instructions below use the automated script [gitian-build.py](gitian-build.py) which only works in Ubuntu.
|
||||
=======
|
||||
The script automatically installs some packages with apt. If you are not running it on a debian-like system, pass `--no-apt` along with the other
|
||||
arguments to it. It calls all available .yml descriptors, which in turn pass the build configurations for different platforms to gitian.
|
||||
@@ -125,23 +122,17 @@ cp monero/contrib/gitian/gitian-build.py .
|
||||
|
||||
### Setup the required environment
|
||||
|
||||
Common setup part:
|
||||
|
||||
```bash
|
||||
su - gitianuser
|
||||
|
||||
GH_USER=YOUR_GITHUB_USER_NAME
|
||||
VERSION=v0.17.2.0
|
||||
```
|
||||
|
||||
Where `GH_USER` is your Github user name and `VERSION` is the version tag you want to build.
|
||||
|
||||
Setup for LXC:
|
||||
|
||||
```bash
|
||||
GH_USER=fluffypony
|
||||
VERSION=v0.17.0.0
|
||||
|
||||
./gitian-build.py --setup $GH_USER $VERSION
|
||||
```
|
||||
|
||||
Where `GH_USER` is your Github user name and `VERSION` is the version tag you want to build.
|
||||
|
||||
Setup for docker:
|
||||
|
||||
```bash
|
||||
@@ -154,10 +145,8 @@ fork the [gitian.sigs repository](https://github.com/monero-project/gitian.sigs)
|
||||
or pass the signed assert file back to your build machine.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/monero-project/gitian.sigs/
|
||||
pushd gitian.sigs
|
||||
git remote add $GH_USER https://github.com/$GH_USER/gitian.sigs
|
||||
popd
|
||||
git clone git@github.com:monero-project/gitian.sigs.git
|
||||
git remote add $GH_USER git@github.com:$GH_USER/gitian.sigs.git
|
||||
```
|
||||
|
||||
Build the binaries
|
||||
@@ -165,26 +154,13 @@ Build the binaries
|
||||
|
||||
**Note:** if you intend to build MacOS binaries, please follow [these instructions](https://github.com/bitcoin-core/docs/blob/master/gitian-building/gitian-building-mac-os-sdk.md) to get the required SDK.
|
||||
|
||||
Currently working MacOS solution:
|
||||
|
||||
```bash
|
||||
curl -O https://bitcoincore.org/depends-sources/sdks/MacOSX10.11.sdk.tar.gz
|
||||
mv MacOSX10.11.sdk.tar.gz builder/inputs
|
||||
```
|
||||
|
||||
To build the most recent tag (pass in `--docker` if using docker):
|
||||
|
||||
```bash
|
||||
./gitian-build.py --detach-sign --no-commit --build $GH_USER $VERSION
|
||||
```
|
||||
|
||||
To speed up the build, use `-j 5 --memory 10000` as the first arguments, where `5` is the number of CPU's you allocated to the VM plus one, and 10000 is a little bit less than then the MB's of RAM you allocated. If there is memory corruption on your machine, try to tweak these values. A good rule of thumb is, that Monero currently needs about 2 GB of RAM per core.
|
||||
|
||||
A full example for `docker` would look like the following:
|
||||
|
||||
```bash
|
||||
./gitian-build.py -j 5 --memory 10000 --docker --detach-sign --no-commit --build $GH_USER $VERSION
|
||||
```
|
||||
To speed up the build, use `-j 5 --memory 5000` as the first arguments, where `5` is the number of CPU's you allocated to the VM plus one, and 5000 is a little bit less than then the MB's of RAM you allocated. If there is memory corruption on your machine, try to tweak these values.
|
||||
|
||||
If all went well, this produces a number of (uncommitted) `.assert` files in the gitian.sigs directory.
|
||||
|
||||
@@ -195,22 +171,6 @@ Take a look in the assert files and note the SHA256 checksums listed there.
|
||||
|
||||
You should verify that the checksum that is listed matches each of the binaries you actually built.
|
||||
This may be done on Linux using the `sha256sum` command or on MacOS using `shasum --algorithm 256` for example.
|
||||
An example script to verify the checksums would be:
|
||||
|
||||
```bash
|
||||
pushd out/${VERSION}
|
||||
|
||||
for ASSERT in ../../sigs/${VERSION}-*/*/*.assert; do
|
||||
if ! sha256sum --ignore-missing -c "${ASSERT}" ; then
|
||||
echo "FAILED for ${ASSERT} ! Please inspect manually."
|
||||
fi
|
||||
done
|
||||
|
||||
popd
|
||||
```
|
||||
|
||||
Don't ignore the incorrect formatting of the found assert files. These files you'll have to compare manually (currently OSX and FreeBSD).
|
||||
|
||||
|
||||
You can also look in the [gitian.sigs](https://github.com/monero-project/gitian.sigs/) repo and / or [getmonero.org release checksums](https://web.getmonero.org/downloads/hashes.txt) to see if others got the same checksum for the same version tag. If there is ever a mismatch -- **STOP! Something is wrong**. Contact others on IRC / github to figure out what is going on.
|
||||
|
||||
@@ -221,7 +181,13 @@ Signing assert files
|
||||
If you chose to do detached signing using `--detach-sign` above (recommended), you need to copy these uncommitted changes to your host machine, then sign them using your gpg key like so:
|
||||
|
||||
```bash
|
||||
for ASSERT in sigs/${VERSION}-*/*/*.assert; do gpg --detach-sign ${ASSERT}; done
|
||||
GH_USER=fluffypony
|
||||
VERSION=v0.17.0.0
|
||||
|
||||
gpg --detach-sign ${VERSION}-linux/${GH_USER}/monero-linux-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-win/${GH_USER}/monero-win-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-osx/${GH_USER}/monero-osx-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-android/${GH_USER}/monero-android-*-build.assert
|
||||
```
|
||||
|
||||
This will create a `.sig` file for each `.assert` file above (2 files for each platform).
|
||||
@@ -234,7 +200,6 @@ Make a pull request (both the `.assert` and `.assert.sig` files) to the
|
||||
[monero-project/gitian.sigs](https://github.com/monero-project/gitian.sigs/) repository:
|
||||
|
||||
```bash
|
||||
cd gitian.sigs
|
||||
git checkout -b $VERSION
|
||||
# add your assert and sig files...
|
||||
git commit -S -a -m "Add $GH_USER $VERSION"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-android-0.10"
|
||||
name: "wownero-android-0.9"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
@@ -94,6 +94,10 @@ def build():
|
||||
os.chdir('builder')
|
||||
os.makedirs('inputs', exist_ok=True)
|
||||
|
||||
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz'])
|
||||
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch'])
|
||||
subprocess.check_output(["echo 'a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 inputs/osslsigncode-Backports-to-1.7.1.patch' | sha256sum -c"], shell=True)
|
||||
subprocess.check_output(["echo 'f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 inputs/osslsigncode-1.7.1.tar.gz' | sha256sum -c"], shell=True)
|
||||
subprocess.check_call(['make', '-C', 'inputs/wownero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
|
||||
|
||||
rebuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-freebsd-0.10"
|
||||
name: "wownero-freebsd-0.9"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
@@ -119,7 +119,7 @@ script: |
|
||||
for i in ${HOSTS}; do
|
||||
export PATH=${WRAP_DIR}:${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_SKIP_RPATH=ON
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DCMAKE_BUILD_TYPE=Release
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-linux-0.10"
|
||||
name: "wownero-linux-0.9"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
@@ -49,7 +49,7 @@ files: []
|
||||
script: |
|
||||
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu i686-linux-gnu"
|
||||
HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu"
|
||||
FAKETIME_HOST_PROGS=""
|
||||
FAKETIME_PROGS="date"
|
||||
HOST_CFLAGS="-O2 -g"
|
||||
@@ -111,11 +111,6 @@ script: |
|
||||
rm -f $WRAP_DIR/extra_includes/i686-linux-gnu/asm
|
||||
ln -s /usr/include/x86_64-linux-gnu/asm $EXTRA_INCLUDES_BASE/i686-linux-gnu/asm
|
||||
|
||||
# glibc 2.23 breaks compatibility with <=2.19 use of lgamma function.
|
||||
# Hack the math header to restore the old behavior.
|
||||
mkdir $EXTRA_INCLUDES_BASE/bits
|
||||
sed -e '/__REDIRFROM .lgamma,/,+3s/_USE_/_DONTUSE_/g' /usr/include/x86_64-linux-gnu/bits/math-finite.h > $EXTRA_INCLUDES_BASE/bits/math-finite.h
|
||||
|
||||
# gcc 7+ honors SOURCE_DATE_EPOCH, no faketime needed
|
||||
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
|
||||
|
||||
@@ -132,14 +127,14 @@ script: |
|
||||
# Build dependencies for each host
|
||||
export TAR_OPTIONS=--mtime=2000-01-01T12:00:00
|
||||
for i in $HOSTS; do
|
||||
ARCH_INCLUDES="$EXTRA_INCLUDES_BASE/$i"
|
||||
if [ -d "$ARCH_INCLUDES" ]; then
|
||||
EXTRA_INCLUDES="${EXTRA_INCLUDES_BASE}:${ARCH_INCLUDES}"
|
||||
EXTRA_INCLUDES="$EXTRA_INCLUDES_BASE/$i"
|
||||
if [ -d "$EXTRA_INCLUDES" ]; then
|
||||
export C_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
else
|
||||
EXTRA_INCLUDES="${EXTRA_INCLUDES_BASE}"
|
||||
unset C_INCLUDE_PATH
|
||||
unset CPLUS_INCLUDE_PATH
|
||||
fi
|
||||
export C_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" V=1
|
||||
done
|
||||
|
||||
@@ -156,15 +151,15 @@ script: |
|
||||
for i in ${HOSTS}; do
|
||||
export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
|
||||
mkdir build && cd build
|
||||
ARCH_INCLUDES="$EXTRA_INCLUDES_BASE/$i"
|
||||
if [ -d "$ARCH_INCLUDES" ]; then
|
||||
EXTRA_INCLUDES="${EXTRA_INCLUDES_BASE}:${ARCH_INCLUDES}"
|
||||
EXTRA_INCLUDES="$EXTRA_INCLUDES_BASE/$i"
|
||||
if [ -d "$EXTRA_INCLUDES" ]; then
|
||||
export C_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
else
|
||||
EXTRA_INCLUDES="${EXTRA_INCLUDES_BASE}"
|
||||
unset C_INCLUDE_PATH
|
||||
unset CPLUS_INCLUDE_PATH
|
||||
fi
|
||||
export C_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=ON -DCMAKE_SKIP_RPATH=ON
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=ON
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-osx-0.10"
|
||||
name: "wownero-osx-0.9"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user