Compare commits

..

8 Commits

Author SHA1 Message Date
R4SAS
31936f6025 [make] change daemon sources list, add unix/win32 depending on system
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-06-08 23:03:52 +03:00
R4SAS
f3dcc5364f [make] update Unix daemon source name
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-06-08 22:57:37 +03:00
R4SAS
fbe2e734c2 [daemon] WIP: rework accessing from webconsole and App
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-06-08 22:51:09 +03:00
R4SAS
78193fc8f8 [daemon] WIP: use callbacks to work with daemon
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-06-08 19:35:23 +03:00
R4SAS
463d43b0bb [cmake] remove HTTPServer.cpp from daemon sources
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-06-08 00:40:50 +03:00
R4SAS
7197fce349 [webconsole] add base templates from current code
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-06-08 00:37:20 +03:00
R4SAS
5ba387ba2b [cmake] add webconsole library
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-06-07 22:50:44 +03:00
R4SAS
a843be75f3 start work on webconsole with templates
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-06-07 22:45:53 +03:00
265 changed files with 34823 additions and 14138 deletions

View File

@@ -1,39 +0,0 @@
# editorconfig.org
root = true
[*]
# Unix style files
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[Makefile,Makefile.*]
indent_style = tab
indent_size = 4
[*.cmd]
indent_style = space
indent_size = 2
end_of_line = crlf
[*.{h,cpp}]
indent_style = tab
indent_size = 4
[*.rc]
indent_style = space
indent_size = 4
[*.{md,markdown}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = false
[*.yml]
indent_style = space
indent_size = 2
[*.patch]
trim_trailing_whitespace = false

View File

@@ -1,39 +0,0 @@
name: Build Debian packages
on: [push, pull_request]
jobs:
build:
name: ${{ matrix.dist }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
dist: ['buster', 'bullseye', 'bookworm']
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Build package
uses: jtdor/build-deb-action@v1
with:
docker-image: debian:${{ matrix.dist }}-slim
buildpackage-opts: --build=binary --no-sign
before-build-hook: debchange --controlmaint --local "+${{ github.sha }}~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build"
extra-build-deps: devscripts git
- name: Upload package
uses: actions/upload-artifact@v3
with:
name: i2pd_${{ matrix.dist }}
path: debian/artifacts/i2pd_*.deb
- name: Upload debugging symbols
uses: actions/upload-artifact@v3
with:
name: i2pd-dbgsym_${{ matrix.dist }}
path: debian/artifacts/i2pd-dbgsym_*.deb

View File

@@ -4,29 +4,18 @@ on: [push, pull_request]
jobs:
build:
runs-on: macos-12
runs-on: macos-10.15
name: with UPnP
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/checkout@v2
- name: Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v0.3.0
uses: vmactions/freebsd-vm@v0.1.5
with:
usesh: true
mem: 2048
sync: rsync
copyback: true
prepare: pkg install -y devel/cmake devel/gmake devel/boost-libs security/openssl net/miniupnpc
prepare: pkg install -y devel/cmake devel/gmake devel/boost-libs security/openssl net/miniupnpc
run: |
cd build
cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release .
gmake -j2
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: i2pd-freebsd
path: build/i2pd

View File

@@ -6,21 +6,15 @@ jobs:
build:
name: With USE_UPNP=${{ matrix.with_upnp }}
runs-on: macOS-latest
strategy:
fail-fast: true
matrix:
with_upnp: ['yes', 'no']
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/checkout@v2
- name: install packages
run: |
find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete
brew update
brew install boost miniupnpc openssl@1.1
- name: build application
run: make HOMEBREW=1 USE_UPNP=${{ matrix.with_upnp }} PREFIX=$GITHUB_WORKSPACE/output -j3

View File

@@ -1,52 +0,0 @@
name: Build on Windows with MSVC
on: [push, pull_request]
jobs:
build:
name: Build
runs-on: windows-latest
strategy:
fail-fast: false
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Build and install zlib
run: |
powershell -Command "(Invoke-WebRequest -Uri https://raw.githubusercontent.com/r4sas/zlib.install/master/install.bat -OutFile install_zlib.bat)"
powershell -Command "(Get-Content install_zlib.bat) | Set-Content install_zlib.bat" # fixing line endings
set BUILD_TYPE=Debug
./install_zlib.bat
set BUILD_TYPE=Release
./install_zlib.bat
del install_zlib.bat
- name: Install Boost
uses: crazy-max/ghaction-chocolatey@v2
with:
args: install boost-msvc-14.3 --version=1.81.0
- name: Install OpenSSL
uses: crazy-max/ghaction-chocolatey@v2
with:
args: install openssl
- name: Configure
working-directory: build
run: cmake -DWITH_STATIC=ON .
- name: Build
working-directory: build
run: cmake --build . --config Debug -- -m
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: i2pd-msvc
path: build/Debug/i2pd.*

View File

@@ -8,106 +8,44 @@ defaults:
jobs:
build:
name: ${{ matrix.arch }}
name: Building using ${{ matrix.arch }} toolchain
runs-on: windows-latest
strategy:
fail-fast: false
fail-fast: true
matrix:
include: [
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc },
{ msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang },
{ msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc },
{ msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc }
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt },
{ msystem: MINGW64, arch: x86_64, arch_short: x64 },
{ msystem: MINGW32, arch: i686, arch_short: x86 }
]
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/checkout@v2
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
install: base-devel git mingw-w64-${{ matrix.arch }}-${{ matrix.compiler }} mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
install: base-devel mingw-w64-${{ matrix.arch }}-gcc mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
update: true
- name: Install additional clang packages
if: ${{ matrix.msystem == 'CLANG64' }}
run: pacman --noconfirm -S mingw-w64-${{ matrix.arch }}-gcc-compat
- name: Build application
run: |
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes -j3
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v2
with:
name: i2pd-${{ matrix.arch_short }}.exe
path: i2pd.exe
build-cmake:
name: CMake ${{ matrix.arch }}
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include: [
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc },
{ msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang },
{ msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc },
{ msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc }
]
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
install: base-devel git mingw-w64-${{ matrix.arch }}-cmake mingw-w64-${{ matrix.arch }}-ninja mingw-w64-${{ matrix.arch }}-${{ matrix.compiler }} mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
update: true
- name: Build application
run: |
cd build
cmake -DWITH_GIT_VERSION=ON -DWITH_STATIC=ON -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release .
cmake --build . -- -j3
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: i2pd-cmake-${{ matrix.arch_short }}.exe
path: build/i2pd.exe
build-xp:
name: XP
name: Building for Windows XP
runs-on: windows-latest
strategy:
fail-fast: false
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/checkout@v2
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW32
install: base-devel git mingw-w64-i686-gcc mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-miniupnpc
update: true
- name: Build WinXP-capable CRT packages
run: |
git clone https://github.com/msys2/MINGW-packages
@@ -126,14 +64,12 @@ jobs:
pacman --noconfirm -U mingw-w64-i686-libwinpthread-git-*-any.pkg.tar.zst mingw-w64-i686-winpthreads-git-*-any.pkg.tar.zst
popd
popd
- name: Build application
run: |
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes USE_WINXP_FLAGS=yes -j3
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v2
with:
name: i2pd-xp.exe
path: i2pd.exe

View File

@@ -5,45 +5,84 @@ on: [push, pull_request]
jobs:
build-make:
name: Make with USE_UPNP=${{ matrix.with_upnp }}
runs-on: ubuntu-latest
runs-on: ubuntu-18.04
strategy:
fail-fast: true
matrix:
with_upnp: ['yes', 'no']
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/checkout@v2
- name: install packages
run: |
sudo add-apt-repository ppa:mhier/libboost-latest
sudo apt-get update
sudo apt-get install build-essential libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev
sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
- name: build application
run: make USE_UPNP=${{ matrix.with_upnp }} -j3
build-cmake:
name: CMake with -DWITH_UPNP=${{ matrix.with_upnp }}
runs-on: ubuntu-latest
runs-on: ubuntu-18.04
strategy:
fail-fast: true
matrix:
with_upnp: ['ON', 'OFF']
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/checkout@v2
- name: install packages
run: |
sudo add-apt-repository ppa:mhier/libboost-latest
sudo apt-get update
sudo apt-get install build-essential cmake libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev
sudo apt-get install build-essential cmake libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
- name: build application
run: |
cd build
cmake -DWITH_UPNP=${{ matrix.with_upnp }} .
make -j3
build-deb-stretch:
name: Build package for stretch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: change debian changelog
run: |
sudo apt-get update
sudo apt-get install devscripts
debchange -v "`git describe --tags`-stretch" -b -M --distribution stretch "trunk build"
- uses: singingwolfboy/build-dpkg-stretch@v1
id: build
with:
args: --unsigned-source --unsigned-changes -b
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename }}
path: ${{ steps.build.outputs.filename }}
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename-dbgsym }}
path: ${{ steps.build.outputs.filename-dbgsym }}
build-deb-buster:
name: Build package for buster
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: change debian changelog
run: |
sudo apt-get update
sudo apt-get install devscripts
debchange -v "`git describe --tags`-buster" -b -M --distribution buster "trunk build"
- uses: singingwolfboy/build-dpkg-buster@v1
id: build
with:
args: --unsigned-source --unsigned-changes -b
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename }}
path: ${{ steps.build.outputs.filename }}
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename-dbgsym }}
path: ${{ steps.build.outputs.filename-dbgsym }}

View File

@@ -4,127 +4,67 @@ on:
push:
branches:
- openssl
- docker
tags:
- '*'
jobs:
build:
name: Building container for ${{ matrix.platform }}
docker:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
strategy:
matrix:
include: [
{ platform: 'linux/amd64', archname: 'amd64' },
{ platform: 'linux/386', archname: 'i386' },
{ platform: 'linux/arm64', archname: 'arm64' },
{ platform: 'linux/arm/v7', archname: 'armv7' },
]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to GitHub Container registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build container for ${{ matrix.archname }}
uses: docker/build-push-action@v3
with:
context: ./contrib/docker
file: ./contrib/docker/Dockerfile
platforms: ${{ matrix.platform }}
push: true
tags: |
purplei2p/i2pd:latest-${{ matrix.archname }}
ghcr.io/purplei2p/i2pd:latest-${{ matrix.archname }}
provenance: false
- name: Build and push trunk container
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: docker/build-push-action@v2
with:
context: ./contrib/docker
file: ./contrib/docker/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7
push: true
tags: |
purplei2p/i2pd:latest
ghcr.io/purplei2p/i2pd:latest
push:
name: Pushing merged manifest
runs-on: ubuntu-latest
- name: Set env
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
permissions:
packages: write
contents: read
needs: build
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push latest manifest image to Docker Hub
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
inputs: purplei2p/i2pd:latest
images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
push: true
- name: Create and push latest manifest image to GHCR
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
inputs: ghcr.io/purplei2p/i2pd:latest
images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
push: true
- name: Store release version to env
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: Create and push release manifest to Docker Hub
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
inputs: purplei2p/i2pd:latest,purplei2p/i2pd:latest-release,purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
push: true
- name: Create and push release manifest to GHCR
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
inputs: ghcr.io/purplei2p/i2pd:latest,ghcr.io/purplei2p/i2pd:latest-release,ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
push: true
- name: Build and push release container
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: docker/build-push-action@v2
with:
context: ./contrib/docker
file: ./contrib/docker/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7
push: true
tags: |
purplei2p/i2pd:latest
purplei2p/i2pd:latest-release
purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
ghcr.io/purplei2p/i2pd:latest
ghcr.io/purplei2p/i2pd:latest-release
ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}

3
.gitignore vendored
View File

@@ -8,12 +8,15 @@ netDb
/libi2pd.a
/libi2pdclient.a
/libi2pdlang.a
/libi2pdwebconsole.a
/libi2pd.so
/libi2pdclient.so
/libi2pdlang.so
/libi2pdwebconsole.so
/libi2pd.dll
/libi2pdclient.dll
/libi2pdlang.dll
/libi2pdwebconsole.dll
*.exe

217
ChangeLog
View File

@@ -1,219 +1,6 @@
# for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog
## [2.49.0] - 2023-09-18
### Added
- Handle SOCK5 authorization with empty user/password
- Drop incoming transport sessions from too old or from future routers
- Memory pool for router profiles
- Allow 0 hops in explicitPeers
### Changed
- Separate network and testing status
- Remove AVX code
- Improve NTCP2 transport session logging
- Select router with ipv4 for tunnel endpoint
- Consider all addresses non-published for U and H routers even if they have host/port
- Don't pick completely unreachable routers for tunnels
- Exclude SSU1 introducers from SSU2 addresses
- Don't create paired inbound tunnel if length is different
- Remove introducer from RouterInfo after 60 minutes
- Reduce SSU2 keep alive interval and add keep alive interval variance
- Don't pick too old sessions for introducer
### Fixed
- Version of the subnegotiation in user/password SOCKS5 response
- Send keepalive for existing session with introducer
- Buffer offset for EVP_EncryptFinal_ex() to include outlen
- Termination block size processing for transport sessions
- Crash if deleted BOB destination was shared between few BOB sessions
- Introducers with zero tag
- Padding for SSU2 path response
## [2.48.0] - 2023-06-12
### Added
- Allow user/password authentication method for SOCK5 proxy
- Publish reject all congestion cap 'G' if transit is not accepted
- 'critical' log level
- Print b32 on webconsole destination page
- Webconsole button to drop a remote LeaseSet
- limits.zombies param - minimum percentage of successfully created tunnels for routers cleanup
- Recognize real routers if successfully connected or responded to tunnel build request
### Changed
- Bypass slow transport sessions for first hop selection
- Limit AESNI inline asm to x86/x64
- Create smaller I2NP packets if possible
- Make router unreachable if AEAD tag verification fails in SessionCreated
- Don't include a router to floodfills list until it's confirmed as real
- Drop LeaseSet store request if not floodfill
- Bypass medium congestion('D') routers for client tunnels
- Publish encrypted RouterInfo through tunnels
- Check if s is valid x25519 public key
- Check if socket is open before sending data in SSU2
### Fixed
- Webconsole empty page if destination is not found
- i2p.streaming.answerPings param
- Reload tunnels
- Address caps for unspecified ipv6 address
- Incomplete HTTP headers in I2P tunnels
- SSU2 socket network exceptions on Windows
- Use of 'server' type tunnel port as inport (#1936)
## [2.47.0] - 2023-03-11
### Added
- Congestion caps
- SAM UDP port parameter
- Support domain addresses for yggdrasil reseeds
### Changed
- DHT for floodfills instead plain list
- Process router's messages in separate thread
- Don't publish non-reachable router
- Send and check target destination in first streaming SYN packet
- Reseeds list
### Fixed
- Memory leak in windows network state detection
- Reseed attempts from invalid address
## [2.46.1] - 2023-02-20
### Fixed
- Race condition while getting router's peer profile
- Creation of new router.info
- Displaying LeaseSets in the webconsole
- Crash when processing ACK request
## [2.46.0] - 2023-02-15
### Added
- Limit number of acked SSU2 packets to 511
- Localization to Swedish, Portuguese, Turkish, Polish
- Periodically send Datetime block in NTCP2 and SSU2
- Don't select random port from reserved
- In memory table for peer profiles
- Store if router was unreachable in it's peer profile
- Show IPv6 addresses in square brackets in webconsole
- Check referer when processing Addresshelper
### Changed
- Algorithm for tunnel creation success rate calculation
- Drop incoming NTCP2 and SSU2 connection if published IP doesn't match actual endpoint
- Exclude actually unreachable router from netdb for 2 hours
- Select first hop from high bandwidth peers for client tunnels
- Drop too long or too short LeaseSet
- Delete router from netdb if became invalid after update
- Terminate existing session if clock skew detected
- Close previous UDP socket if open before reopening
- Minimal version for floodfill is 0.9.51
- Sort transports by endpoints in webconsole
### Fixed
- Deadlock during processing I2NP block with Garlic in ECIES encrypted message to router
- Race condition with encrypted LeaseSets
- HTTP query detection
- Connection attempts to IPs from invalid ranges
- Publish "0.0.0.0" in RouterInfo
- Crash upon receiving PeerTest 7
- Tunnels for closed SAM session socket
- Missing NTCP2 address in RouterInfo if enabled back
## [2.45.1] - 2023-01-11
### Added
- Full Cone NAT status error
### Changed
- Drop duplicated I2NP messages in SSU2
- Set rejection code 30 if tunnel with id already exists
- Network status is always OK if peer test msg 5 received
### Fixed
- UPnP crash if SSU2 or NTCP2 is disabled
- Crash on termination for some platforms
## [2.45.0] - 2023-01-03
### Added
- Test for Symmetric NAT with peer test msgs 6 and 7
- Webconsole "No Descriptors" router error state
- 1 and 15 seconds bandwidth calculation for i2pcontrol
- Show non-zero send queue size for transports in web console
- Compressible padding for I2P addresses
- Localization to Czech
- Don't accept incoming session from invalid/reserved addresses for NTCP2 and SSU2
- Limit simultaneous tunnel build requests by 4 per pool
### Changed
- Removed SSU support
- Reduced bandwidth calculation interval from 60 to 15 seconds
- Increased default max transit tunnels number from 2500 to 5000 or 10000 for floodfill
- Transit tunnels limit is doubled if floodfill mode is enabled
- NTCP2 and SSU2 timestamps are rounded to seconds
- Drop RouterInfos and LeaseSets with timestamp from future
- Don't delete unreachable routers if tunnel creation success rate is too low
- Refuse duplicated incoming pending NTCP2 session from same IP
- Don't send SSU2 termination again if termination received block received
- Handle standard network error for SSU2 without throwing an exception
- Don't select overloaded peer for next tunnel
- Remove "X-Requested-With" in HTTP Proxy for non-AJAX requests
### Fixed
- File descriptors leak
- Random crash on AddressBook update
- Crash if incorrect LeaseSet size
- Spamming to log if no descriptors
- ::1 address in RouterInfo
- SSU2 network error handling (especially for Windows)
- Race condition with pending outgoing SSU2 sessions
- RTT self-reduction for long-live streams
## [2.44.0] - 2022-11-20
### Added
- SSL connection for server I2P tunnels
- Localization to Italian and Spanish
- SSU2 through SOCKS5 UDP proxy
- Reload tunnels through web console
- SSU2 send immediate ack request flag
- SSU2 send and verify path challenge
- Configurable ssu2.mtu4 and ssu2.mtu6
### Changed
- SSU2 is enabled and SSU is disabled by default
- Separate network status and error
- Random selection between NTCP2 and SSU2 priority
- Added notbob.i2p to jump services
- Remove DoNotTrack flag from HTTP Request header
- Skip addresshelper page if destination was not changed
- SSU2 allow different ports from RelayReponse and HolePunch
- SSU2 resend PeerTest msg 1 and msg 2
- SSU2 Send Retry instead SessionCreated if clock skew detected
### Fixed
- Long HTTP headers for HTTP proxy and HTTP server tunnel
- SSU2 resends and resend limits
- Crash at startup if addressbook is disabled
- NTCP2 ipv6 connection through SOCKS5 proxy
- SSU2 SessionRequest with zero token
- SSU2 MTU less than 1280
- SSU2 port=1
- Incorrect addresses from network interfaces
- Definitions for Darwin PPC; do not use pthread_setname_np
## [2.43.0] - 2022-08-22
### Added
- Complete SSU2 implementation
- Localization to Chinese
- Send RouterInfo update for long live sessions
- Explicit ipv6 ranges of known tunnel brokers for MTU detection
- Always send "Connection: close" and strip out Keep-Alive for server HTTP tunnel
- Show ports for all transports in web console
- Translation of webconsole site title
- Support for Windows ProgramData path when running as service
- Ability to turn off address book
- Handle signals TSTP and CONT to stop and resume network
### Changed
- Case insensitive headers for server HTTP tunnel
- Do not show 'Address registration' line if LeaseSet is encrypted
- SSU2 transports have higher priority than SSU
- Disable ElGamal precalculated table if no SSU
- Deprecate limits.ntcpsoft, limits.ntcphard and limits.ntcpthreads config options
- SSU2 is enabled and SSU is disabled by default for new installations
### Fixed
- Typo with Referer header name in HTTP proxy
- Can't handle garlic message from an exploratory tunnel
- Incorrect encryption key for exploratory lookup reply
- Bound checks issues in LeaseSets code
- MTU detection on Windows
- Crash on stop of active server tunnel
- Send datagram to wrong destination in SAM
- Incorrect static key in RouterInfo if the keys were regenerated
- Duplicated sessions in BOB
## [2.42.1] - 2022-05-24
### Fixed
- Incorrect jump link in HTTP Proxy
@@ -594,7 +381,7 @@
### Added
- Client auth flag for b33 address
### Changed
- Remove incoming NTCP2 session from pending list when established
- Remove incoming NTCP2 session from pending list when established
- Handle errors for NTCP2 SessionConfrimed send
### Fixed
- Failure to start on Windows XP
@@ -898,7 +685,7 @@
### Added
- Datagram i2p tunnels
- Unique local addresses for server tunnels
- Configurable list of reseed servers and initial addressbook
- Configurable list of reseed servers and initial addressbook
- Configurable netid
- Initial iOS support

View File

@@ -1,4 +1,4 @@
Copyright (c) 2013-2023, The PurpleI2P Project
Copyright (c) 2013-2020, The PurpleI2P Project
All rights reserved.

View File

@@ -12,19 +12,22 @@ endif
SHLIB := libi2pd.$(SHARED_SUFFIX)
ARLIB := libi2pd.a
SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX)
ARLIB_LANG := libi2pdlang.a
SHLIB_CLIENT := libi2pdclient.$(SHARED_SUFFIX)
ARLIB_CLIENT := libi2pdclient.a
SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX)
ARLIB_LANG := libi2pdlang.a
SHLIB_WEBCONSOLE := libi2pdwebconsole.$(SHARED_SUFFIX)
ARLIB_WEBCONSOLE := libi2pdwebconsole.a
SHLIB_WRAP := libi2pdwrapper.$(SHARED_SUFFIX)
ARLIB_WRAP := libi2pdwrapper.a
I2PD := i2pd
LIB_SRC_DIR := libi2pd
LIB_CLIENT_SRC_DIR := libi2pd_client
WRAP_SRC_DIR := libi2pd_wrapper
WEBCONSOLE_SRC_DIR := libi2pd_webconsole
LANG_SRC_DIR := i18n
DAEMON_SRC_DIR := daemon
WRAP_SRC_DIR := libi2pd_wrapper
# import source files lists
include filelist.mk
@@ -47,62 +50,59 @@ else
LD_DEBUG = -s
endif
ifneq (, $(DESTDIR))
PREFIX = $(DESTDIR)
endif
ifneq (, $(findstring darwin, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonUnix.cpp
ifeq ($(HOMEBREW),1)
include Makefile.homebrew
else
include Makefile.osx
endif
else ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32Service.cpp Win32/Win32NetState.cpp
include Makefile.mingw
else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonUnix.cpp
include Makefile.linux
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonUnix.cpp
include Makefile.bsd
else ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32Service.cpp Win32/Win32NetState.cpp
include Makefile.mingw
else # not supported
$(error Not supported platform)
endif
INCFLAGS += -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR)
DEFINES += -DOPENSSL_SUPPRESS_DEPRECATED
NEEDED_CXXFLAGS += -MMD -MP
ifeq ($(USE_GIT_VERSION),yes)
GIT_VERSION := $(shell git describe --tags)
DEFINES += -DGITVER=$(GIT_VERSION)
NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\"
endif
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR) -I$(WEBCONSOLE_SRC_DIR) -DOPENSSL_SUPPRESS_DEPRECATED
LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
WEBCONSOLE_OBJS += $(patsubst %.cpp,obj/%.o,$(WEBCONSOLE_SRC))
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC))
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d)
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(WEBCONSOLE_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d)
## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary
all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD)
all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(ARLIB_WEBCONSOLE) $(I2PD)
mk_obj_dir:
@mkdir -p obj/$(LIB_SRC_DIR)
@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
@mkdir -p obj/$(LANG_SRC_DIR)
@mkdir -p obj/$(WEBCONSOLE_SRC_DIR)
@mkdir -p obj/$(DAEMON_SRC_DIR)
@mkdir -p obj/$(WRAP_SRC_DIR)
@mkdir -p obj/Win32
api: $(SHLIB) $(ARLIB)
client: $(SHLIB_CLIENT) $(ARLIB_CLIENT)
lang: $(SHLIB_LANG) $(ARLIB_LANG)
api_client: api client lang
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
api: $(SHLIB) $(ARLIB)
client: $(SHLIB_CLIENT) $(ARLIB_CLIENT)
lang: $(SHLIB_LANG) $(ARLIB_LANG)
webconsole: $(SHLIB_WEBCONSOLE) $(ARLIB_WEBCONSOLE)
api_client: api client lang webconsole
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
## **without** overwriting the CXXFLAGS which we need in order to build.
@@ -112,17 +112,17 @@ wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
## custom FLAGS to work at build-time.
obj/%.o: %.cpp | mk_obj_dir
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(DEFINES) $(INCFLAGS) -c -o $@ $<
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $<
# '-' is 'ignore if missing' on first run
-include $(DEPS)
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
$(CXX) -o $@ $(DEFINES) $(LDFLAGS) $^ $(LDLIBS)
$(I2PD): $(DAEMON_OBJS) $(ARLIB_WEBCONSOLE) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
$(SHLIB): $(LIB_OBJS)
$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG)
ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB_LANG)
endif
$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) $(SHLIB) $(SHLIB_LANG)
@@ -130,12 +130,17 @@ ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_LANG)
endif
$(SHLIB_WRAP): $(WRAP_LIB_OBJS)
$(SHLIB_LANG): $(LANG_OBJS)
ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
endif
$(SHLIB_LANG): $(LANG_OBJS)
$(SHLIB_WEBCONSOLE): $(WEBCONSOLE_OBJS) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
endif
$(SHLIB_WRAP): $(WRAP_LIB_OBJS)
ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
endif
@@ -146,18 +151,21 @@ $(ARLIB): $(LIB_OBJS)
$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS)
$(AR) -r $@ $^
$(ARLIB_WRAP): $(WRAP_LIB_OBJS)
$(ARLIB_LANG): $(LANG_OBJS)
$(AR) -r $@ $^
$(ARLIB_LANG): $(LANG_OBJS)
$(ARLIB_WEBCONSOLE): $(WEBCONSOLE_OBJS)
$(AR) -r $@ $^
$(ARLIB_WRAP): $(WRAP_LIB_OBJS)
$(AR) -r $@ $^
clean:
$(RM) -r obj
$(RM) -r docs/generated
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WRAP) $(ARLIB_WRAP)
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WEBCONSOLE) $(ARLIB_WEBCONSOLE) $(SHLIB_WRAP) $(ARLIB_WRAP)
strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG) $(SHLIB_WEBCONSOLE)
strip $^
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)

View File

@@ -6,8 +6,7 @@ CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misl
## (e.g. -fstack-protector-strong -Wformat -Werror=format-security), we do not want to remove
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
## custom FLAGS to work at build-time.
NEEDED_CXXFLAGS = -std=c++11
DEFINES = -D_GLIBCXX_USE_NANOSLEEP=1
NEEDED_CXXFLAGS = -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
INCFLAGS = -I/usr/include/ -I/usr/local/include/
LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread

View File

@@ -39,18 +39,13 @@ ifeq ($(USE_AESNI),yes)
endif
install: all
install -d ${PREFIX}/bin
install -m 755 ${I2PD} ${PREFIX}/bin
install -d ${PREFIX}/etc ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d
install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd
install -m 755 ${I2PD} ${PREFIX}/bin/
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
install -d ${PREFIX}/share ${PREFIX}/share/doc ${PREFIX}/share/doc/i2pd
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
install -d ${PREFIX}/share/i2pd
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
install -d ${PREFIX}/share/man ${PREFIX}/share/man/man1
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
@gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
install -d ${PREFIX}/var ${PREFIX}/var/lib ${PREFIX}/var/lib/i2pd
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/certificates
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/var/lib/i2pd/tunnels.d
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt

View File

@@ -20,11 +20,7 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[8-9]"),3) # gcc 4.8 - 4.9
else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6
NEEDED_CXXFLAGS += -std=c++11
LDLIBS = -latomic
else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc 7 - 9
NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -latomic
else ifeq ($(shell expr match ${CXXVER} "1[0-9]"),2) # gcc 10+
# NEEDED_CXXFLAGS += -std=c++20
else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7
NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -latomic
else # not supported
@@ -58,29 +54,23 @@ endif
# UPNP Support (miniupnpc 1.5 and higher)
ifeq ($(USE_UPNP),yes)
DEFINES += -DUSE_UPNP
NEEDED_CXXFLAGS += -DUSE_UPNP
endif
ifeq ($(USE_AESNI),yes)
ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64, $(SYS))) # only x86-based CPU supports that
NEEDED_CXXFLAGS += -maes
DEFINES += -D__AES__
NEEDED_CXXFLAGS += -D__AES__ -maes
endif
endif
install: all
install -d ${PREFIX}/bin
install -m 755 ${I2PD} ${PREFIX}/bin
install -d ${PREFIX}/etc ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d
install -d ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/usr ${PREFIX}/usr/share ${PREFIX}/usr/share/doc/i2pd ${PREFIX}/usr/share/i2pd ${PREFIX}/usr/share/man ${PREFIX}/usr/share/man/man1 ${PREFIX}/var/lib ${PREFIX}/var/lib/i2pd
install -m 755 ${I2PD} ${PREFIX}/bin/
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
install -d ${PREFIX}/share ${PREFIX}/share/doc ${PREFIX}/share/doc/i2pd
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
install -d ${PREFIX}/share/i2pd
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
install -d ${PREFIX}/share/man ${PREFIX}/share/man/man1
@gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
install -d ${PREFIX}/var ${PREFIX}/var/lib ${PREFIX}/var/lib/i2pd
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/certificates
@cp -R contrib/certificates ${PREFIX}/usr/share/i2pd/
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/usr/share/doc/i2pd
@gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/usr/share/man/man1
@ln -sf ${PREFIX}/usr/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/var/lib/i2pd/tunnels.d
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt

View File

@@ -4,18 +4,17 @@ USE_WIN32_APP := yes
WINDRES = windres
CXXFLAGS := $(CXX_DEBUG) -fPIC -msse
INCFLAGS := -I$(DAEMON_SRC_DIR) -IWin32
INCFLAGS = -IWin32
LDFLAGS := ${LD_DEBUG} -static
NEEDED_CXXFLAGS += -std=c++17
DEFINES += -DWIN32_LEAN_AND_MEAN
NEEDED_CXXFLAGS += -std=c++17 -DWIN32_LEAN_AND_MEAN
# Boost libraries suffix
BOOST_SUFFIX = -mt
# UPNP Support
ifeq ($(USE_UPNP),yes)
DEFINES += -DUSE_UPNP -DMINIUPNP_STATICLIB
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
LDLIBS = -lminiupnpc
endif
@@ -36,19 +35,18 @@ LDLIBS += \
-lpthread
ifeq ($(USE_WIN32_APP), yes)
DEFINES += -DWIN32_APP
NEEDED_CXXFLAGS += -DWIN32_APP
LDFLAGS += -mwindows
DAEMON_RC += Win32/Resource.rc
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
endif
ifeq ($(USE_WINXP_FLAGS), yes)
DEFINES += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
NEEDED_CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
endif
ifeq ($(USE_AESNI),yes)
NEEDED_CXXFLAGS += -maes
DEFINES += -D__AES__
NEEDED_CXXFLAGS += -D__AES__ -maes
endif
ifeq ($(USE_ASLR),yes)
@@ -56,4 +54,4 @@ ifeq ($(USE_ASLR),yes)
endif
obj/%.o : %.rc | mk_obj_dir
$(WINDRES) $(DEFINES) $(INCFLAGS) --preprocessor-arg=-MMD --preprocessor-arg=-MP --preprocessor-arg=-MF$@.d -i $< -o $@
$(WINDRES) -i $< -o $@

View File

@@ -1,7 +1,6 @@
CXX = clang++
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX
INCFLAGS = -I/usr/local/include
DEFINES := -DMAC_OSX
LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib
LDFLAGS += -Wl,-dead_strip
LDFLAGS += -Wl,-dead_strip_dylibs
@@ -15,7 +14,7 @@ endif
ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl
DEFINES += -DUSE_UPNP
CXXFLAGS += -DUSE_UPNP
ifeq ($(USE_STATIC),yes)
LDLIBS += /usr/local/lib/libminiupnpc.a
else
@@ -23,12 +22,8 @@ ifeq ($(USE_UPNP),yes)
endif
endif
OSARCH = $(shell uname -p)
ifneq ($(OSARCH),powerpc)
ifeq ($(USE_AESNI),yes)
CXXFLAGS += -D__AES__ -maes
else
CXXFLAGS += -msse
endif
ifeq ($(USE_AESNI),yes)
CXXFLAGS += -D__AES__ -maes
else
CXXFLAGS += -msse
endif

View File

@@ -69,12 +69,12 @@ Build instructions:
**Supported systems:**
* GNU/Linux (Debian, Ubuntu, etc) - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml)
* CentOS, Fedora, Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
* Alpine, ArchLinux, openSUSE, Gentoo, etc.
* GNU/Linux - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml)
* CentOS / Fedora / Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
* Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc.
* Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml)
* Mac OS - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml)
* Docker image - [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml)
* Mac OS X - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml)
* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml)
* Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd)
* FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml)
* Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml)
@@ -99,23 +99,13 @@ Current status: [![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](http
Donations
---------
**E-Mail**: ```i2porignal at yandex.ru```
**BTC**: ```3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f```
**LTC**: ```LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59```
**ETH**: ```0x9e5bac70d20d1079ceaa111127f4fb3bccce379d```
**GST**: ```GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG```
**DASH**: ```Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF```
**ZEC**: ```t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ```
**ANC**: ```AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z```
**XMR**: ```497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH```
BTC: 3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d
DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG
XMR: 497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH
License
-------

View File

@@ -1,36 +1,36 @@
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "winres.h"
#undef APSTUDIO_READONLY_SYMBOLS
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
MAINICON ICON "mask.ico"
#endif // English (United States) resources
#ifndef APSTUDIO_INVOKED
#include "Resource.rc2"
#endif // not APSTUDIO_INVOKED
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "winres.h"
#undef APSTUDIO_READONLY_SYMBOLS
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
MAINICON ICON "mask.ico"
#endif // English (United States) resources
#ifndef APSTUDIO_INVOKED
#include "Resource.rc2"
#endif // not APSTUDIO_INVOKED

View File

@@ -2,7 +2,7 @@
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
#include "version.h"
#include "../libi2pd/version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH
@@ -25,7 +25,7 @@ BEGIN
VALUE "FileDescription", "C++ I2P daemon"
VALUE "FileVersion", I2PD_VERSION
VALUE "InternalName", CODENAME
VALUE "LegalCopyright", "Copyright (C) 2013-2023, The PurpleI2P Project"
VALUE "LegalCopyright", "Copyright (C) 2013-2022, The PurpleI2P Project"
VALUE "OriginalFilename", "i2pd"
VALUE "ProductName", "Purple I2P"
VALUE "ProductVersion", I2P_VERSION

View File

@@ -18,7 +18,7 @@
#include "Tunnel.h"
#include "version.h"
#include "resource.h"
#include "Daemon.h"
#include "Win32App.h"
#include "Win32NetState.h"
@@ -45,7 +45,6 @@ namespace i2p
namespace win32
{
DWORD g_GracefulShutdownEndtime = 0;
bool g_isWinService;
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
{
@@ -56,13 +55,15 @@ namespace win32
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
if(!i2p::context.AcceptsTunnels())
InsertMenu (hPopup, -1,
i2p::util::DaemonWin32::Instance ().isGraceful ? MF_BYPOSITION | MF_STRING | MF_GRAYED : MF_BYPOSITION | MF_STRING,
ID_ACCEPT_TRANSIT, "Accept &transit");
if(m_getIsGraceful)
if(m_getIsGraceful())
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING | MF_GRAYED, ID_ACCEPT_TRANSIT, "Accept &transit");
else
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ACCEPT_TRANSIT, "Accept &transit");
else
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config");
if (!i2p::util::DaemonWin32::Instance ().isGraceful)
if (!m_getIsGraceful)
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
else
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown");
@@ -145,34 +146,35 @@ namespace win32
s << bytes << " Bytes\n";
}
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, bool testing)
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status)
{
switch (status)
{
case eRouterStatusOK: s << "OK"; break;
case eRouterStatusTesting: s << "Test"; break;
case eRouterStatusFirewalled: s << "FW"; break;
case eRouterStatusUnknown: s << "Unk"; break;
case eRouterStatusProxy: s << "Proxy"; break;
case eRouterStatusMesh: s << "Mesh"; break;
default: s << "Unk";
};
if (testing)
s << " (Test)";
if (i2p::context.GetError () != eRouterErrorNone)
{
switch (i2p::context.GetError ())
case eRouterStatusError:
{
case eRouterErrorClockSkew:
s << " - Clock skew";
s << "Err";
switch (i2p::context.GetError ())
{
case eRouterErrorClockSkew:
s << " - Clock skew";
break;
case eRouterErrorOffline:
s << " - Offline";
break;
case eRouterErrorSymmetricNAT:
s << " - Symmetric NAT";
break;
default: ;
}
break;
case eRouterErrorOffline:
s << " - Offline";
break;
case eRouterErrorSymmetricNAT:
s << " - Symmetric NAT";
break;
default: ;
}
default: s << "Unk";
}
}
@@ -180,11 +182,11 @@ namespace win32
{
s << "\n";
s << "Status: ";
ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetTesting ());
ShowNetworkStatus (s, i2p::context.GetStatus ());
if (i2p::context.SupportsV6 ())
{
s << " / ";
ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetTestingV6 ());
ShowNetworkStatus (s, i2p::context.GetStatusV6 ());
}
s << "; ";
s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n";
@@ -270,7 +272,7 @@ namespace win32
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second
g_GracefulShutdownEndtime = GetTickCount() + 10*60*1000;
i2p::util::DaemonWin32::Instance ().isGraceful = true;
if (m_setIsGraceful) m_setIsGraceful(true);
return 0;
}
case ID_STOP_GRACEFUL_SHUTDOWN:
@@ -279,7 +281,7 @@ namespace win32
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
g_GracefulShutdownEndtime = 0;
i2p::util::DaemonWin32::Instance ().isGraceful = false;
if (m_setIsGraceful) m_setIsGraceful(false);
return 0;
}
case ID_RELOAD:
@@ -349,9 +351,6 @@ namespace win32
}
}
}
#if (__cplusplus >= 201703L) // C++ 17 or higher
[[fallthrough]];
#endif
}
case WM_TRAYICON:
{
@@ -421,9 +420,8 @@ namespace win32
return DefWindowProc( hWnd, uMsg, wParam, lParam);
}
bool StartWin32App (bool isWinService)
bool StartWin32App ()
{
g_isWinService = isWinService;
if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")))
{
MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK);
@@ -452,9 +450,7 @@ namespace win32
MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST);
return false;
}
// COM requires message loop to work, which is not implemented in service mode
if (!g_isWinService)
SubscribeToEvents();
SubscribeToEvents();
return true;
}
@@ -474,8 +470,7 @@ namespace win32
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
if (hWnd)
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0);
else if(!g_isWinService)
UnSubscribeFromEvents();
// UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app
UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -17,11 +17,20 @@ namespace win32
{
extern DWORD g_GracefulShutdownEndtime;
bool StartWin32App (bool isWinService);
bool StartWin32App ();
void StopWin32App ();
int RunWin32App ();
bool GracefulShutdown ();
bool StopGracefulShutdown ();
inline typedef std::function<void (bool)> DaemonSetIsGraceful;
inline DaemonSetIsGraceful m_setIsGraceful;
inline void SetIsGraceful (const DaemonSetIsGraceful& f) { m_setIsGraceful = f; };
inline typedef std::function<bool ()> DaemonGetIsGraceful;
inline DaemonGetIsGraceful m_getIsGraceful;
inline void GetIsGraceful (const DaemonGetIsGraceful& f) { m_getIsGraceful = f; };
}
}
#endif // WIN32APP_H__

View File

@@ -15,7 +15,6 @@ IUnknown *pUnknown = nullptr;
INetworkListManager *pNetworkListManager = nullptr;
IConnectionPointContainer *pCPContainer = nullptr;
IConnectionPoint *pConnectPoint = nullptr;
CNetworkListManagerEvent *pNetEvent = nullptr;
DWORD Cookie = 0;
void SubscribeToEvents()
@@ -30,11 +29,7 @@ void SubscribeToEvents()
if (SUCCEEDED(Result))
{
VARIANT_BOOL IsConnect = VARIANT_FALSE;
#if defined(_MSC_VER)
Result = pNetworkListManager->get_IsConnectedToInternet(&IsConnect);
#else
Result = pNetworkListManager->IsConnectedToInternet(&IsConnect);
#endif
if (SUCCEEDED(Result)) {
i2p::transport::transports.SetOnline (true);
LogPrint(eLogInfo, "NetState: Current state: ", IsConnect == VARIANT_TRUE ? "connected" : "disconnected");
@@ -46,8 +41,8 @@ void SubscribeToEvents()
Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint);
if(SUCCEEDED(Result))
{
pNetEvent = new CNetworkListManagerEvent;
Result = pConnectPoint->Advise((IUnknown *)pNetEvent, &Cookie);
CNetworkListManagerEvent *NetEvent = new CNetworkListManagerEvent;
Result = pConnectPoint->Advise((IUnknown *)NetEvent, &Cookie);
if (SUCCEEDED(Result))
LogPrint(eLogInfo, "NetState: Successfully subscribed to NetworkListManagerEvent messages");
else
@@ -64,7 +59,6 @@ void SubscribeToEvents()
void UnSubscribeFromEvents()
{
LogPrint(eLogInfo, "NetState: Unsubscribing from NetworkListManagerEvents");
try
{
if (pConnectPoint) {
@@ -72,9 +66,6 @@ void UnSubscribeFromEvents()
pConnectPoint->Release();
}
if (pNetEvent)
pNetEvent->Release();
if (pCPContainer)
pCPContainer->Release();

View File

@@ -19,18 +19,21 @@ class CNetworkListManagerEvent : public INetworkListManagerEvents
{
public:
CNetworkListManagerEvent() : m_ref(1) { }
~CNetworkListManagerEvent() { }
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
{
HRESULT Result = S_OK;
if (IsEqualIID(riid, IID_IUnknown)) {
*ppvObject = (IUnknown *)this;
} else if (IsEqualIID(riid ,IID_INetworkListManagerEvents)) {
*ppvObject = (INetworkListManagerEvents *)this;
} else {
return E_NOINTERFACE;
Result = E_NOINTERFACE;
}
AddRef();
return S_OK;
return Result;
}
ULONG STDMETHODCALLTYPE AddRef()

View File

@@ -10,7 +10,6 @@
#include <assert.h>
#include <windows.h>
#include "Daemon.h"
#include "Log.h"
I2PService *I2PService::s_service = NULL;
@@ -21,7 +20,7 @@ BOOL I2PService::isService()
HWINSTA hWinStation = GetProcessWindowStation();
if (hWinStation != NULL)
{
USEROBJECTFLAGS uof = { FALSE, FALSE, 0 };
USEROBJECTFLAGS uof = { 0 };
if (GetUserObjectInformation(hWinStation, UOI_FLAGS, &uof, sizeof(USEROBJECTFLAGS), NULL) && ((uof.dwFlags & WSF_VISIBLE) == 0))
{
bIsService = TRUE;
@@ -119,12 +118,12 @@ void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
}
catch (DWORD dwError)
{
LogPrint(eLogCritical, "Win32Service: Start error: ", dwError);
LogPrint(eLogError, "Win32Service: Start error: ", dwError);
SetServiceStatus(SERVICE_STOPPED, dwError);
}
catch (...)
{
LogPrint(eLogCritical, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_STOPPED);
}
}
@@ -132,7 +131,13 @@ void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
{
LogPrint(eLogInfo, "Win32Service: in OnStart (", EVENTLOG_INFORMATION_TYPE, ")");
Daemon.start();
if(m_daemonStart)
m_daemonStart();
else
{
LogPrint(eLogError, "Win32Service: failed to start: Unable to call callback");
SetServiceStatus(SERVICE_STOPPED);
}
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this));
}
@@ -162,7 +167,7 @@ void I2PService::Stop()
}
catch (...)
{
LogPrint(eLogCritical, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(dwOriginalState);
}
}
@@ -171,7 +176,11 @@ void I2PService::OnStop()
{
// Log a service stop message to the Application log.
LogPrint(eLogInfo, "Win32Service: in OnStop (", EVENTLOG_INFORMATION_TYPE, ")");
Daemon.stop();
if(m_daemonStop)
m_daemonStop();
else
LogPrint(eLogError, "Win32Service: failed to stop: Unable to call callback");
m_fStopping = TRUE;
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
{
@@ -191,12 +200,12 @@ void I2PService::Pause()
}
catch (DWORD dwError)
{
LogPrint(eLogCritical, "Win32Service: Pause error: ", dwError);
LogPrint(eLogError, "Win32Service: Pause error: ", dwError);
SetServiceStatus(SERVICE_RUNNING);
}
catch (...)
{
LogPrint(eLogCritical, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_RUNNING);
}
}
@@ -215,12 +224,12 @@ void I2PService::Continue()
}
catch (DWORD dwError)
{
LogPrint(eLogCritical, "Win32Service: Continue error: ", dwError);
LogPrint(eLogError, "Win32Service: Continue error: ", dwError);
SetServiceStatus(SERVICE_PAUSED);
}
catch (...)
{
LogPrint(eLogCritical, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_PAUSED);
}
}
@@ -238,11 +247,11 @@ void I2PService::Shutdown()
}
catch (DWORD dwError)
{
LogPrint(eLogCritical, "Win32Service: Shutdown error: ", dwError);
LogPrint(eLogError, "Win32Service: Shutdown error: ", dwError);
}
catch (...)
{
LogPrint(eLogCritical, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
}
}

View File

@@ -6,9 +6,10 @@
* See full license text in LICENSE file at top of project tree
*/
#ifndef WIN_32_SERVICE_H__
#define WIN_32_SERVICE_H__
#ifndef WIN32SERVICE_H__
#define WIN32SERVICE_H__
#include <functional>
#include <thread>
#include <windows.h>
@@ -29,6 +30,13 @@ class I2PService
static BOOL Run(I2PService &service);
void Stop();
typedef std::function<bool ()> DaemonStart;
void SetDaemonStart (const DaemonStart& f) { m_daemonStart = f; };
typedef std::function<bool ()> DaemonStop;
void SetDaemonStop (const DaemonStop& f) { m_daemonStop = f; };
protected:
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
@@ -58,6 +66,11 @@ class I2PService
HANDLE m_hStoppedEvent;
std::thread* _worker;
private:
DaemonStart m_daemonStart;
DaemonStop m_daemonStop;
};
#endif // WIN_32_SERVICE_H__
#endif // WIN32SERVICE_H__

BIN
Win32/mask.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

14
build/.gitignore vendored
View File

@@ -1,13 +1,6 @@
# Various generated files
/CMakeFiles/
/Testing/
/tests/
/.ninja_*
/arch.c
/build.ninja
/i2pd
/i2pd.exe
/i2pd.exe.debug
/libi2pd.a
/libi2pdclient.a
/libi2pdlang.a
@@ -15,13 +8,8 @@
/CMakeCache.txt
/CPackConfig.cmake
/CPackSourceConfig.cmake
/CTestTestfile.cmake
/install_manifest.txt
/Makefile
/arch.c
# windows build script
i2pd*.zip
build*.log
# MVS project files
*.vcxproj
*.vcxproj.filters
*.sln

View File

@@ -1,32 +1,14 @@
cmake_minimum_required(VERSION 3.7)
if(${CMAKE_VERSION} VERSION_LESS 3.22)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
else()
cmake_policy(VERSION 3.22)
endif()
cmake_policy(VERSION 3.7)
project("i2pd")
# for debugging
#set(CMAKE_VERBOSE_MAKEFILE on)
# paths
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
set(LIBI2PD_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd)
set(LIBI2PD_CLIENT_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd_client)
set(LANG_SRC_DIR ${CMAKE_SOURCE_DIR}/i18n)
set(DAEMON_SRC_DIR ${CMAKE_SOURCE_DIR}/daemon)
include(Version)
set_version("${LIBI2PD_SRC_DIR}/version.h" PROJECT_VERSION)
project(
i2pd
VERSION ${PROJECT_VERSION}
HOMEPAGE_URL "https://i2pd.website/"
LANGUAGES CXX
)
# Win32 build with cmake is not supported
if(WIN32 OR MSVC OR MSYS OR MINGW)
message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.")
endif()
# configurable options
option(WITH_AESNI "Use AES-NI instructions set" ON)
@@ -35,31 +17,32 @@ option(WITH_LIBRARY "Build library" ON)
option(WITH_BINARY "Build binary" ON)
option(WITH_STATIC "Static build" OFF)
option(WITH_UPNP "Include support for UPnP client" OFF)
option(WITH_GIT_VERSION "Use git commit info as version" OFF)
option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF)
option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
option(BUILD_TESTING "Build tests" OFF)
IF(BUILD_TESTING)
enable_testing()
ENDIF()
# paths
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
set(CMAKE_SOURCE_DIR "..")
# Handle paths nicely
#Handle paths nicely
include(GNUInstallDirs)
# Architecture
# architecture
include(TargetArch)
target_architecture(ARCHITECTURE)
include(CheckAtomic)
if(WITH_STATIC)
if(MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
endif()
set(LIBI2PD_SRC_DIR ../libi2pd)
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
set(WEBCONSOLE_SRC_DIR ../libi2pd_webconsole)
set(LANG_SRC_DIR ../i18n)
set(DAEMON_SRC_DIR ../daemon)
include_directories(${LIBI2PD_SRC_DIR})
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
include_directories(${WEBCONSOLE_SRC_DIR})
include_directories(${LANG_SRC_DIR})
include_directories(${DAEMON_SRC_DIR})
FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp)
add_library(libi2pd ${LIBI2PD_SRC})
set_target_properties(libi2pd PROPERTIES PREFIX "")
@@ -70,9 +53,11 @@ if(WITH_LIBRARY)
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Libraries)
# TODO Make libi2pd available to 3rd party projects via CMake as imported target
# FIXME This pulls stdafx
# install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
FILE(GLOB CLIENT_SRC ${LIBI2PD_CLIENT_SRC_DIR}/*.cpp)
add_library(libi2pdclient ${CLIENT_SRC})
set_target_properties(libi2pdclient PROPERTIES PREFIX "")
@@ -85,7 +70,18 @@ if(WITH_LIBRARY)
COMPONENT Libraries)
endif()
include_directories(${LANG_SRC_DIR})
FILE(GLOB WEBCONSOLE_SRC ${WEBCONSOLE_SRC_DIR}/*.cpp)
add_library(libi2pdwebconsole ${WEBCONSOLE_SRC})
set_target_properties(libi2pdwebconsole PROPERTIES PREFIX "")
if(WITH_LIBRARY)
install(TARGETS libi2pdwebconsole
EXPORT libi2pdwebconsole
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Libraries)
endif()
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
add_library(libi2pdlang ${LANG_SRC})
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
@@ -98,74 +94,38 @@ if(WITH_LIBRARY)
COMPONENT Libraries)
endif()
include_directories(${DAEMON_SRC_DIR})
set(DAEMON_SRC
"${DAEMON_SRC_DIR}/Daemon.cpp"
"${DAEMON_SRC_DIR}/HTTPServer.cpp"
"${DAEMON_SRC_DIR}/I2PControl.cpp"
"${DAEMON_SRC_DIR}/I2PControlHandlers.cpp"
"${DAEMON_SRC_DIR}/i2pd.cpp"
"${DAEMON_SRC_DIR}/UPnP.cpp"
)
if(WIN32)
set(WIN32_SRC_DIR ${CMAKE_SOURCE_DIR}/Win32)
include_directories(${WIN32_SRC_DIR})
list(APPEND DAEMON_SRC
"${WIN32_SRC_DIR}/DaemonWin32.cpp"
"${WIN32_SRC_DIR}/Win32App.cpp"
"${WIN32_SRC_DIR}/Win32Service.cpp"
"${WIN32_SRC_DIR}/Win32NetState.cpp"
)
file(GLOB WIN32_RC ${WIN32_SRC_DIR}/*.rc)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_APP -DWIN32_LEAN_AND_MEAN")
endif()
if(WITH_UPNP)
add_definitions(-DUSE_UPNP)
endif()
if(WITH_GIT_VERSION)
include(GetGitRevisionDescription)
git_describe(GIT_VERSION)
add_definitions(-DGITVER=${GIT_VERSION})
endif()
if(APPLE)
add_definitions(-DMAC_OSX)
endif()
if(MSVC)
add_definitions(-DWINVER=0x0600)
add_definitions(-D_WIN32_WINNT=0x0600)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
# Multiple definitions of __stack_chk_fail(libssp & libc)
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections")
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above
# check for c++17 & c++11 support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED)
CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED)
if(CXX17_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
elseif(CXX11_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter -Wno-uninitialized")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
# Multiple definitions of __stack_chk_fail(libssp & libc)
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s")
endif()
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -ffunction-sections -fdata-sections")
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above
# check for c++17 & c++11 support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED)
CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED)
if(CXX17_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
elseif(CXX11_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?")
endif()
message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@@ -188,7 +148,7 @@ endif()
# compiler flags customization(by system)
if(UNIX)
list(APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
list(APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/DaemonUnix.cpp")
if(NOT(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE))
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8
add_definitions("-D_GLIBCXX_USE_NANOSLEEP=1")
@@ -197,11 +157,8 @@ endif()
# Note: AES-NI and AVX is available on x86-based CPU's.
# Here also ARM64 implementation, but currently we don't support it.
# MSVC is not supported due to different ASM processing, so we hope OpenSSL has its own checks to run optimized code.
if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386"))
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
add_definitions(-D__AES__)
endif()
@@ -219,48 +176,15 @@ if(WITH_THREADSANITIZER)
endif()
endif()
# Use std::atomic instead of GCC builtins on macOS PowerPC:
# For more information refer to: https://github.com/PurpleI2P/i2pd/issues/1726#issuecomment-1306335111
# This has been fixed in Boost 1.81, nevertheless we retain the setting for the sake of compatibility.
if(APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
add_definitions(-DBOOST_SP_USE_STD_ATOMIC)
endif()
# libraries
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
if(WITH_STATIC)
if(NOT MSVC)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
endif()
set(Boost_USE_STATIC_LIBS ON)
if(MSVC)
set(Boost_USE_STATIC_RUNTIME ON)
else()
set(Boost_USE_STATIC_RUNTIME OFF)
endif()
if(MSVC)
set(OPENSSL_MSVC_STATIC_RT ON)
endif()
set(OPENSSL_USE_STATIC_LIBS ON)
set(ZLIB_USE_STATIC_LIBS ON)
if(MSVC)
set(ZLIB_NAMES zlibstatic zlibstat)
else()
set(ZLIB_NAMES libz zlibstatic zlibstat zlib z)
endif()
if(WITH_UPNP)
set(MINIUPNPC_USE_STATIC_LIBS ON)
add_definitions(-DMINIUPNP_STATICLIB)
endif()
set(Boost_USE_STATIC_RUNTIME ON)
set(BUILD_SHARED_LIBS OFF)
if(${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
# set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive")
@@ -270,23 +194,19 @@ else()
# TODO: Consider separate compilation for LIBI2PD_SRC for library.
# No need in -fPIC overhead for binary if not interested in library
# HINT: revert c266cff CMakeLists.txt: compilation speed up
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()
add_definitions(-DBOOST_ATOMIC_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
if(WIN32)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_STATIC_RUNTIME OFF)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
endif()
find_package(Boost REQUIRED COMPONENTS system filesystem program_options date_time OPTIONAL_COMPONENTS atomic)
if(NOT DEFINED Boost_FOUND)
target_link_libraries(libi2pdwebconsole libi2pdclient libi2pd libi2pdlang)
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
if(NOT DEFINED Boost_INCLUDE_DIRS)
message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!")
endif()
find_package(OpenSSL REQUIRED)
if(NOT DEFINED OPENSSL_FOUND)
if(NOT DEFINED OPENSSL_INCLUDE_DIR)
message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!")
endif()
@@ -311,6 +231,8 @@ endif()
# load includes
include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
include(CheckAtomic)
# show summary
message(STATUS "---------------------------------------")
message(STATUS "Build type : ${CMAKE_BUILD_TYPE}")
@@ -326,64 +248,40 @@ message(STATUS " LIBRARY : ${WITH_LIBRARY}")
message(STATUS " BINARY : ${WITH_BINARY}")
message(STATUS " STATIC BUILD : ${WITH_STATIC}")
message(STATUS " UPnP : ${WITH_UPNP}")
if(WITH_GIT_VERSION)
message(STATUS " GIT VERSION : ${WITH_GIT_VERSION} (${GIT_VERSION})")
else()
message(STATUS " GIT VERSION : ${WITH_GIT_VERSION}")
endif()
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
message(STATUS "---------------------------------------")
if(WITH_BINARY)
if(WIN32)
add_executable("${PROJECT_NAME}" WIN32 ${DAEMON_SRC} ${WIN32_RC})
else()
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
endif()
if(WIN32)
list(APPEND MINGW_EXTRA "wsock32" "ws2_32" "iphlpapi")
# OpenSSL may require Crypt32 library on MSVC build, which is not added by CMake lesser than 3.21
if(MSVC AND ${CMAKE_VERSION} VERSION_LESS 3.21)
list(APPEND MINGW_EXTRA "crypt32")
endif()
endif()
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
if(WITH_STATIC)
if(NOT MSVC)
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
endif()
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
endif()
if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now")
endif()
if(WITH_UPNP)
set(UPNP_LIB ${MINIUPNPC_LIBRARY})
endif()
# FindBoost pulls pthread for thread which is broken for static linking at least on Ubuntu 15.04
list(GET Boost_LIBRARIES -1 LAST_Boost_LIBRARIES)
if(${LAST_Boost_LIBRARIES} MATCHES ".*pthread.*")
list(REMOVE_AT Boost_LIBRARIES -1)
endif()
# synchronization library is incompatible with Windows 7
if(WIN32)
get_target_property(BOOSTFSLIBS Boost::filesystem INTERFACE_LINK_LIBRARIES)
list(REMOVE_ITEM BOOSTFSLIBS synchronization)
set_target_properties(Boost::filesystem PROPERTIES INTERFACE_LINK_LIBRARIES "${BOOSTFSLIBS}")
endif()
if(WITH_STATIC)
set(DL_LIB ${CMAKE_DL_LIBS})
endif()
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY})
target_link_libraries("${PROJECT_NAME}" libi2pdwebconsole libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} Threads::Threads ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
set(DIRS "${Boost_LIBRARY_DIR};${OPENSSL_INCLUDE_DIR}/../bin;${ZLIB_INCLUDE_DIR}/../bin;/mingw32/bin")
endif()
if(BUILD_TESTING)
add_subdirectory(${CMAKE_SOURCE_DIR}/tests ${CMAKE_CURRENT_BINARY_DIR}/tests)
endif()

View File

@@ -1,23 +1,18 @@
# atomic builtins are required for threading support.
INCLUDE(CheckCXXSourceCompiles)
INCLUDE(CheckLibraryExists)
# Sometimes linking against libatomic is required for atomic ops, if
# the platform doesn't support lock-free atomics.
function(check_working_cxx_atomics varname)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
CHECK_CXX_SOURCE_COMPILES("
#include <atomic>
std::atomic<int> x;
std::atomic<short> y;
std::atomic<char> z;
int main() {
++z;
++y;
return ++x;
return x;
}
" ${varname})
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
@@ -32,7 +27,6 @@ function(check_working_cxx_atomics64 varname)
std::atomic<uint64_t> x (0);
int main() {
uint64_t i = x.load(std::memory_order_relaxed);
(void)i;
return 0;
}
" ${varname})
@@ -40,16 +34,15 @@ int main() {
endfunction(check_working_cxx_atomics64)
# Check for (non-64-bit) atomic operations.
if(MSVC)
set(HAVE_CXX_ATOMICS_WITHOUT_LIB True)
else()
# This isn't necessary on MSVC, so avoid command-line switch annoyance
# by only running on GCC-like hosts.
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
# First check if atomics work without the library.
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
if(HAVE_LIBATOMIC)
if( HAVE_LIBATOMIC )
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
@@ -65,20 +58,20 @@ endif()
if(MSVC)
set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
else()
# First check if atomics work without the library.
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
if(HAVE_CXX_LIBATOMICS64)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
endif()
else()
message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
endif()
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
if(HAVE_CXX_LIBATOMICS64)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
message(FATAL_ERROR "Host compiler must support std::atomic!")
endif()
else()
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
endif()
endif()
@@ -87,6 +80,7 @@ endif()
## assumes C++11 <atomic> works.
CHECK_CXX_SOURCE_COMPILES("
#ifdef _MSC_VER
#include <Intrin.h> /* Workaround for PR19898. */
#include <windows.h>
#endif
int main() {

View File

@@ -1,55 +0,0 @@
# - Try to find the CHECK libraries
# Once done this will define
#
# CHECK_FOUND - system has check
# CHECK_INCLUDE_DIRS - the check include directory
# CHECK_LIBRARIES - check library
#
# Copyright (c) 2007 Daniel Gollub <gollub@b1-systems.de>
# Copyright (c) 2007-2009 Bjoern Ricks <bjoern.ricks@gmail.com>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
INCLUDE( FindPkgConfig )
IF ( Check_FIND_REQUIRED )
SET( _pkgconfig_REQUIRED "REQUIRED" )
ELSE( Check_FIND_REQUIRED )
SET( _pkgconfig_REQUIRED "" )
ENDIF ( Check_FIND_REQUIRED )
IF ( CHECK_MIN_VERSION )
PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check>=${CHECK_MIN_VERSION} )
ELSE ( CHECK_MIN_VERSION )
PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check )
ENDIF ( CHECK_MIN_VERSION )
# Look for CHECK include dir and libraries
IF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND )
FIND_PATH( CHECK_INCLUDE_DIRS check.h )
FIND_LIBRARY( CHECK_LIBRARIES NAMES check )
IF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES )
SET( CHECK_FOUND 1 )
IF ( NOT Check_FIND_QUIETLY )
MESSAGE ( STATUS "Found CHECK: ${CHECK_LIBRARIES}" )
ENDIF ( NOT Check_FIND_QUIETLY )
ELSE ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES )
IF ( Check_FIND_REQUIRED )
MESSAGE( FATAL_ERROR "Could NOT find CHECK" )
ELSE ( Check_FIND_REQUIRED )
IF ( NOT Check_FIND_QUIETLY )
MESSAGE( STATUS "Could NOT find CHECK" )
ENDIF ( NOT Check_FIND_QUIETLY )
ENDIF ( Check_FIND_REQUIRED )
ENDIF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES )
ENDIF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND )
# Hide advanced variables from CMake GUIs
MARK_AS_ADVANCED( CHECK_INCLUDE_DIRS CHECK_LIBRARIES )

View File

@@ -1,284 +0,0 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the working tree (--dirty option),
# and adjusting the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# git_local_changes(<var>)
#
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
# Uses the return code of "git diff-index --quiet HEAD --".
# Does not regard untracked files.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
# http://academic.cleardefinition.com
#
# Copyright 2009-2013, Iowa State University.
# Copyright 2013-2020, Ryan Pavlik
# Copyright 2013-2020, Contributors
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
# Function _git_find_closest_git_dir finds the next closest .git directory
# that is part of any directory in the path defined by _start_dir.
# The result is returned in the parent scope variable whose name is passed
# as variable _git_dir_var. If no .git directory can be found, the
# function returns an empty string via _git_dir_var.
#
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
# neither foo nor bar contain a file/directory .git. This wil return
# C:/bla/.git
#
function(_git_find_closest_git_dir _start_dir _git_dir_var)
set(cur_dir "${_start_dir}")
set(git_dir "${_start_dir}/.git")
while(NOT EXISTS "${git_dir}")
# .git dir not found, search parent directories
set(git_previous_parent "${cur_dir}")
get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
if(cur_dir STREQUAL git_previous_parent)
# We have reached the root directory, we are not in git
set(${_git_dir_var}
""
PARENT_SCOPE)
return()
endif()
set(git_dir "${cur_dir}/.git")
endwhile()
set(${_git_dir_var}
"${git_dir}"
PARENT_SCOPE)
endfunction()
function(get_git_head_revision _refspecvar _hashvar)
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
else()
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
endif()
if(NOT "${GIT_DIR}" STREQUAL "")
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
"${GIT_DIR}")
if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
# We've gone above the CMake root dir.
set(GIT_DIR "")
endif()
endif()
if("${GIT_DIR}" STREQUAL "")
set(${_refspecvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
set(${_hashvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# Check if the current source dir is a git submodule or a worktree.
# In both cases .git is a file instead of a directory.
#
if(NOT IS_DIRECTORY ${GIT_DIR})
# The following git command will return a non empty string that
# points to the super project working tree if the current
# source dir is inside a git submodule.
# Otherwise the command will return an empty string.
#
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse
--show-superproject-working-tree
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT "${out}" STREQUAL "")
# If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
${submodule})
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
ABSOLUTE)
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
else()
# GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
file(READ ${GIT_DIR} worktree_ref)
# The .git directory contains a path to the worktree information directory
# inside the parent git repo of the worktree.
#
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
${worktree_ref})
string(STRIP ${git_worktree_dir} git_worktree_dir)
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
endif()
else()
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake" @ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar}
"${HEAD_REF}"
PARENT_SCOPE)
set(${_hashvar}
"${HEAD_HASH}"
PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_describe_working_tree _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_local_changes _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var}
"CLEAN"
PARENT_SCOPE)
else()
set(${_var}
"DIRTY"
PARENT_SCOPE)
endif()
endfunction()

View File

@@ -1,43 +0,0 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright 2009-2012, Iowa State University
# Copyright 2011-2015, Contributors
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# SPDX-License-Identifier: BSL-1.0
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2017-2023, The PurpleI2P Project
# Copyright (c) 2017-2022, The PurpleI2P Project
# This file is part of Purple i2pd project and licensed under BSD3
# See full license text in LICENSE file at top of project tree
@@ -18,7 +18,7 @@ set(archdetect_c_code "
|| defined(_M_ARM64) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8)
#error cmake_ARCH arm64
#elif defined(__ARM_ARCH_7__) \\
#if defined(__ARM_ARCH_7__) \\
|| defined(__ARM_ARCH_7A__) \\
|| defined(__ARM_ARCH_7R__) \\
|| defined(__ARM_ARCH_7M__) \\
@@ -61,7 +61,7 @@ set(archdetect_c_code "
#else
#error cmake_ARCH mips
#endif
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(__POWERPC__) \\
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|| defined(_M_MPPC) || defined(_M_PPC)
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
@@ -83,13 +83,13 @@ function(target_architecture output_var)
# First let's normalize the order of the values
# Note that it's not possible to compile PowerPC applications if you are using
# the OS X SDK version 10.7 or later - you'll need 10.4/10.5/10.6 for that, so we
# disable it by default. Also, ppc64 is not supported in 10.6.
# the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
# disable it by default
# See this page for more information:
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
# Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise; 10.6 also supports ppc.
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
@@ -133,11 +133,11 @@ function(target_architecture output_var)
enable_language(C)
# Detect the architecture in a rather creative way...
# This compiles a small C program which is a series of ifdefs that selects
# a particular #error preprocessor directive whose message string contains
# the target architecture. The program will always fail to compile (both because
# file is not a valid C program, and obviously because of the presence of
# the #error preprocessor directives... but by exploiting the preprocessor in this
# This compiles a small C program which is a series of ifdefs that selects a
# particular #error preprocessor directive whose message string contains the
# target architecture. The program will always fail to compile (both because
# file is not a valid C program, and obviously because of the presence of the
# #error preprocessor directives... but by exploiting the preprocessor in this
# way, we can detect the correct target architecture even when cross-compiling,
# since the program itself never needs to be run (only the compiler/preprocessor)
try_run(

View File

@@ -1,16 +0,0 @@
# read version
function(set_version version_file output_var)
file(READ "${version_file}" version_data)
string(REGEX MATCH "I2PD_VERSION_MAJOR ([0-9]*)" _ ${version_data})
set(version_major ${CMAKE_MATCH_1})
string(REGEX MATCH "I2PD_VERSION_MINOR ([0-9]*)" _ ${version_data})
set(version_minor ${CMAKE_MATCH_1})
string(REGEX MATCH "I2PD_VERSION_MICRO ([0-9]*)" _ ${version_data})
set(version_micro ${CMAKE_MATCH_1})
set(${output_var} "${version_major}.${version_minor}.${version_micro}" PARENT_SCOPE)
endfunction()

View File

@@ -1,34 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIF2TCCA8GgAwIBAgIQIHQPtSoFU+cUpYD8PZaWZjANBgkqhkiG9w0BAQsFADB2
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEfMB0GA1UEAwwW
YXJuYXZiaGF0dDI4OEBtYWlsLmkycDAeFw0yMzAxMjUxODUzNDFaFw0zMzAxMjUx
ODUzNDFaMHYxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgx
HjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMR8w
HQYDVQQDDBZhcm5hdmJoYXR0Mjg4QG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEAtwG73sC0jYd3fgEzZh0SveAdUd5yD35nINJRrdPSrSwY
n3i1qGe3fNLj877PvUDU+qiHH0fFZfyFkXTaq3TUp1u4YkmvaoPHy6FZlojB08lK
FBm+iJ1hifQ7MFmvIKUGv+cjlN6xSoQ0U6B2QOy6iZnBgFZ/7jbRY4iZOIj7VJtY
aodeHfy0bWe447VJovbkUi7NJPFZQS65LMcAIWcWTxrC0Gj8SmdxL3a5+hxpmmg0
+KCQvWQDdxAQjsc16sgUCdUc6cWYO4yw9H6fgdq9GJX+LnXR9OB58GsAjjlLlFoI
CZxdARDpoqcIj6AoKIanALf8yfbIyrqqJE47cuaqV9bht5MWKnXbwHplEkT4ZNkh
PnRDia7B5HY3uwbt39CBm264PEWXvWG2sozTWKQqBjmMN2cj/NFDUEqKv6BggMY1
HcqxWFKRcgKCtRvrmTmfp5l0/ou+OtUaFUg0a6Qhtb93Hj10vK6wZzidBqj0ggzB
eJDI95b89u8JgzRoOBriuMKTc91WTkOvBLkB3dgUbUpx2p8KHjvf/pppBH9u0oxp
qJFFK840DbnJydEvjKezeVe5Ax6YRSRxyEdKzRoWdvKVxb3qBBKMdCKTYEPxHPBu
JMEQVUCXJMti++1KEiQGhcfWvLyT7OewbcIZNk9XWNrxlKcGrTp9AOwaaNC5m1kC
AwEAAaNjMGEwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr
BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB8GA1UdDgQYBBZhcm5hdmJoYXR0Mjg4
QG1haWwuaTJwMA0GCSqGSIb3DQEBCwUAA4ICAQAHiK0ld/1PF9DIhutD660/bzBg
mF2Z76hcBqDZ8tnQai/u/RXYrH9wso9BYyrVsvk3fr6tpGT49Ian0MVpPOxMoTU2
oBEmQlYrfclQLFsOLmA0y2r1ggXzIrt69jB710Vhwdnz09oOE8rS4E2T5oDD8Wvy
Kony+AarRceqtkOlzyquc42KjzdrbHsosF7G2iGhNI6t+T3BfWJ+Q+d5sj3OIh6e
gSfvHL44E4vZt6dtofRN3MAZ60kNLF5YWyaUo3Snv9Lso1IwIz3AVr5ehv+8sFL/
KxaXdkZ5Yn2YUX7p1t4VQd+eXVPYjf1befg4PvrwSkylu3Jpee3fllZSKXeSVx9x
jpJiq5vIakqk22pnWb1Vn7xzSW1vtEG7QLjobOr1WrcGiwdv+HKiWcXJXDzKoWXs
h3VEfr51Kap8cIJv+D6lJIG9IcIhiQ6CXWBmtjWJvbdVwFBy1/3Fhaou9liHi+gK
4Yh5a5OGCzc7xjtpGaTmoLEz7NzDNOdd/r840qRDOh70izzmFZd5Gwq4hoVcPJcS
EAySwtgqK0/4d0zDd2Wg9ASJV9DnDf8QuSmHZgZ9Efs47XcWz9TvkWUS1E66AJsN
mmI1NDQ3mv3dv5+WPq+dqqYFsnx3xWL1g5Z3buk0opeuXMzoHwM7UfN8h7Q1M5+t
+XBgkaYA4iEwYKqlCQ==
-----END CERTIFICATE-----

View File

@@ -1,33 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFvjCCA6agAwIBAgIQBnsUOmOu2oZZIwHBmQc1BDANBgkqhkiG9w0BAQsFADBt
MIIFvjCCA6agAwIBAgIQIDtv8tGMh0FyB2w5XjfZxTANBgkqhkiG9w0BAQsFADBt
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwN
aWdvckBub3ZnLm5ldDAeFw0yMzAxMjgxNDM4MzFaFw0zMzAxMjgxNDM4MzFaMG0x
aWdvckBub3ZnLm5ldDAeFw0xNzA3MjQxODI4NThaFw0yNzA3MjQxODI4NThaMG0x
CzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNVBAoT
FUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1p
Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLkf
bM3uiYfp9m0vgdoftyXtk2/9bHf3u5iaM0WfoJIsw1iizo/mxJl+Iy7SxLC16nV0
v5FpncVv+Z8x9dgoAYVuLq9zKfsAbpj6kuxAqw6vJMlD1TiIL3nSODV9BJLk47X5
tmvoOSj9BgvemYThTE3nj+DbuJRW5q90KyBV/LdLrQJX3k5R3FFL5tTad2LKFNZ4
vEOcYwwx6mvrkJ2lly6bAQUCtfc648Jyq+NO3Rba1fmn7gcP9zXXc5KYsj/ovyY2
OaocSF5wMhzBuPxO+M2HqbYLMAkc6/GesGds8Rm8wofuhJoI5YtqJuLKZm6nQXSc
fx6PKgbKcTIUWNFMsxyfghz9hpbg0rkvC7PtfAjtV0yaDtUum1eZeNEx1HbRWN2n
TQNCVuv0yaKC41qxqzhEybkdjL9JlgUh7VuskaCelB0lz+kgYjGu8ezOa0ua2iKq
4FC/1MbPulxN8NOt4pmbGqqoxmCdShp38wdnOBM3DsAS9f0JaQZd4CDyY4DCSfVn
xPdWk31+VXVt3Ixh1EUqZWYTRSsZApkCyYzkiZ/qPGG6FR9Hq2SuhC5o4P44k7eo
6wwBWD8a5RjsZhvr05E5yBrKXh/PjLwmtG73QC+ouR54/5xtedvdTwNS94FnNctX
FT6QGZnRwCkhPaRe1oQMzP+88pGoCfO33GBAuwUCAwEAAaNaMFgwDgYDVR0PAQH/
Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxst4
cam3YibBtQHGPCPX13uRQti56U3XZytSZntaKrUFmJxjt41Q/mOy3KYo+lBvhfDF
x3tWKjgP9LJOJ28zvddFhZVNxqZRjcnAoPuSOVCw88g01D9OAasKF11hCfdxZP6h
vGm8WCnjD8KPcYFxJC4HJUiFeProAwuTzEAESTRk4CAQe3Ie91JspuqoLUc5Qxlm
w5QpjnjfZY4kaVHmZDKGIZDgNIt5v85bu4pWwZ6O+o90xQqjxvjyz/xccIec3sHw
MHJ8h8ZKMokCKEJTaRWBvdeNXki7nf3gUy/3GjYQlzo0Nxk/Hw4svPcA+eL0AYiy
Jn83bIB5VToW2zYUdV4u3qHeAhEg8Y7HI0kKcSUGm9AQXzbzP8YCHxi0sbb0GAJy
f1Xf3XzoPfT64giD8ReUHhwKpyMB6uvG/NfWSZAzeAO/NT7DAwXpKIVQdkVdqy8b
mvHvjf9/kWKOirA2Nygf3r79Vbg2mqbYC/b63XI9hheU689+O7qyhTEhNz+11X0d
Zax7UPrLrwOeB9TNfEnztsmrHNdv2n+KcOO2o11Wvz2nHP9g+dgwoZSD1ZEpFzWP
0sD5knKLwAL/64qLlAQ1feqW7hMr80IADcKjLSODkIDIIGm0ksXqEzTjz1JzbRDq
jUjq7EAlkw3G69rv1gHxIntllJRQidAqecyWHOMCAwEAAaNaMFgwDgYDVR0PAQH/
BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8E
BTADAQH/MBYGA1UdDgQPBA1pZ29yQG5vdmcubmV0MA0GCSqGSIb3DQEBCwUAA4IC
AQCteAb5/bqhHr/i5CJbDzlofprXFC826c19GxQ/9Hw0kA52l0J9Q8Vz8Vy7VQyP
QNa8MCv6FeNy8a/wXp6cafyFsBtvehVQO8lFlpCgMEl2Bma43+GaCwkrM6bFNXeW
iQ9h4e1KjsUZ8cQDNEcamiJ80+xbMhBrj5bAZwKmZs8MoGEMyXKEZmcmwA+/fy1c
cx4izsOsmRXmEHXsvB9ydJHZZeKW8+r0DAtgPslwXuXHG6MuBQo7dKCqn+iMxHXV
Jxriq3yvNffdGx4maSLJrjQ1ealt/UMzql7huVSItnVFWoYf7GAELXNJ/PmqVyaK
q11LQ8W/Aud6s/bblaJrFJnK8PbPpaw4RvHoWVLYaZYmQnV2msWs5EuESBlEADbv
UklQXLMc2f9HKWPA5678nvYPrmu8IL5pMkAxgGRqmd+7vCz4lU9M5z3HObU+WRBt
qEMYyXywV8o3tbmnlDS5S5Xxf+tLZn1cxz3ZrmcHPHDbLBNdvszF3CTJH/R2sQvD
bizvYJM+p5F+GWM5mt6w0HrOut5MRlpOws/NRrkbijuVA/A45nzTtKplIFYE3qe8
q5SAbwYLc8cJcZCN3PxtWwbEv81V33abMt5QcjnWGLH5t2+1Z2KLCgKLSCQTxM8s
zBPHtUe8qtSQaElnNLILYbtJ1w67dPnGYTphHihC+CXjBg==
AQADyPaec28qc1HQtAV5dscJr47k92RTfvan+GEgIwyQDHZQm38eyTb05xipQCdk
5ruUDFXLB5qXXFJKUbQM6IpaktmWDJqk4Zn+1nGbtFEbKgrF55pd63+NQer5QW9o
3+dGj0eZJa3HX5EBkd2r7j2LFuB6uxv3r/xiTeHaaflCnsmyDLfb7axvYhyEzHQS
AUi1bR+ln+dXewdtuojqc1+YmVGDgzWZK2T0oOz2E21CpZUDiP3wv9QfMaotLEal
zECnbhS++q889inN3GB4kIoN6WpPpeYtTV+/r7FLv9+KUOV1s2z6mxIqC5wBFhZs
0Sr1kVo8hB/EW/YYhDp99LoAOjIO6nn1h+qttfzBYr6C16j+8lGK2A12REJ4LiUQ
cQI/0zTjt2C8Ns6ueNzMLQN1Mvmlg1Z8wIB7Az7jsIbY2zFJ0M5qR5VJveTj33K4
4WSbC/zMWOBYHTVBvGmc6JGhu5ZUTZ+mWP7QfimGu+tdhvtrybFjE9ROIE/4yFr6
GkxEyt0UY87TeKXJ/3KygvkMwdvqGWiZhItb807iy99+cySujtbGfF2ZXYGjBXVW
dJOVRbyGQkHh6lrWHQM4ntBv4x+5QA+OAan5PBF3tcDx1vefPx+asYslbOXpzII5
qhvoQxuRs6j5jsVFG6RdsKNeQAt87Mb2u2zK2ZakMdyD1w==
-----END CERTIFICATE-----

View File

@@ -1,5 +1,2 @@
This forder contain files required for building debian packages.
The trunk repository is contains the packaging files for the latest stable version of Debian (if we not forgot to update them).
Files in subdirectories contains fixes to make possible to build package on specific versions of Debian/Ubuntu. They are used when building the release package.
This forder contain systemd unit files.
To use systemd daemon control, place files from this directory to debian folder before building package.

View File

@@ -1 +0,0 @@
11

View File

@@ -1,18 +0,0 @@
Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 11~), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 4.2.0
Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd
Architecture: any
Pre-Depends: ${misc:Pre-Depends}, adduser
Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base,
Description: Full-featured C++ implementation of I2P client.
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.

View File

@@ -1 +0,0 @@
9

View File

@@ -1,18 +0,0 @@
Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 9), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 3.9.8
Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd
Architecture: any
Pre-Depends: ${misc:Pre-Depends}, adduser
Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base,
Description: Full-featured C++ implementation of I2P client.
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.

View File

@@ -1,19 +0,0 @@
Description: Disable LogsDirectory and LogsDirectoryMode options in service
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2023-05-17
--- a/contrib/i2pd.service
+++ b/contrib/i2pd.service
@@ -8,8 +8,8 @@ User=i2pd
Group=i2pd
RuntimeDirectory=i2pd
RuntimeDirectoryMode=0700
-LogsDirectory=i2pd
-LogsDirectoryMode=0700
+#LogsDirectory=i2pd
+#LogsDirectoryMode=0700
Type=forking
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
ExecReload=/bin/sh -c "kill -HUP $MAINPID"

View File

@@ -1,2 +0,0 @@
01-upnp.patch
02-service.patch

View File

@@ -1,18 +0,0 @@
#!/usr/bin/make -f
#export DH_VERBOSE=1
export DEB_BUILD_MAINT_OPTIONS=hardening=+all
include /usr/share/dpkg/architecture.mk
ifeq ($(DEB_HOST_ARCH),i386)
export DEB_BUILD_OPTIONS=parallel=1
endif
export DEB_CXXFLAGS_MAINT_APPEND=-Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND=
%:
dh $@ --parallel
override_dh_auto_install:

View File

@@ -1 +0,0 @@
9

View File

@@ -1,18 +0,0 @@
Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 9), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 3.9.8
Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd
Architecture: any
Pre-Depends: ${misc:Pre-Depends}, adduser
Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base,
Description: Full-featured C++ implementation of I2P client.
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.

View File

@@ -1,17 +0,0 @@
Description: Enable UPnP usage in package
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2022-03-23
--- i2pd.orig/Makefile
+++ i2pd/Makefile
@@ -31,7 +31,7 @@ include filelist.mk
USE_AESNI := $(or $(USE_AESNI),yes)
USE_STATIC := $(or $(USE_STATIC),no)
-USE_UPNP := $(or $(USE_UPNP),no)
+USE_UPNP := $(or $(USE_UPNP),yes)
DEBUG := $(or $(DEBUG),yes)
# for debugging purposes only, when commit hash needed in trunk builds in i2pd version string

View File

@@ -1,19 +0,0 @@
Description: Disable LogsDirectory and LogsDirectoryMode options in service
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2023-05-17
--- a/contrib/i2pd.service
+++ b/contrib/i2pd.service
@@ -8,8 +8,8 @@ User=i2pd
Group=i2pd
RuntimeDirectory=i2pd
RuntimeDirectoryMode=0700
-LogsDirectory=i2pd
-LogsDirectoryMode=0700
+#LogsDirectory=i2pd
+#LogsDirectoryMode=0700
Type=forking
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
ExecReload=/bin/sh -c "kill -HUP $MAINPID"

View File

@@ -1,2 +0,0 @@
01-upnp.patch
02-service.patch

View File

@@ -1,13 +0,0 @@
#!/usr/bin/make -f
#export DH_VERBOSE=1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
include /usr/share/dpkg/architecture.mk
export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND =
%:
dh $@ --parallel
override_dh_auto_install:

View File

@@ -1,8 +0,0 @@
type = bgprocess
run-as = i2pd
command = /usr/bin/i2pd --conf=/var/lib/i2pd/i2pd.conf --pidfile=/var/lib/i2pd/i2pd.pid --daemon --service
smooth-recovery = true
depends-on = ntpd
# uncomment if you want to use i2pd with yggdrasil
# depends-on = yggdrasil
pid-file = /var/lib/i2pd/i2pd.pid

View File

@@ -1,18 +1,5 @@
#
# Copyright (c) 2017-2022, The PurpleI2P Project
#
# This file is part of Purple i2pd project and licensed under BSD3
#
# See full license text in LICENSE file at top of project tree
#
FROM alpine:latest
LABEL authors="Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>"
LABEL maintainer="R4SAS <r4sas@i2pmail.org>"
LABEL org.opencontainers.image.source=https://github.com/PurpleI2P/i2pd
LABEL org.opencontainers.image.documentation=https://i2pd.readthedocs.io/en/latest/
LABEL org.opencontainers.image.licenses=BSD3
LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>"
# Expose git branch, tag and URL variables as arguments
ARG GIT_BRANCH="openssl"
@@ -24,28 +11,27 @@ ENV REPO_URL=${REPO_URL}
ENV I2PD_HOME="/home/i2pd"
ENV DATA_DIR="${I2PD_HOME}/data"
ENV DEFAULT_ARGS=" --datadir=$DATA_DIR"
ENV DEFAULT_ARGS=" --datadir=$DATA_DIR --reseed.verify=true --upnp.enabled=false --http.enabled=true --http.address=0.0.0.0 --httpproxy.enabled=true --httpproxy.address=0.0.0.0 --socksproxy.enabled=true --socksproxy.address=0.0.0.0 --sam.enabled=true --sam.address=0.0.0.0"
RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \
&& adduser -S -h "$I2PD_HOME" i2pd \
&& chown -R i2pd:nobody "$I2PD_HOME"
# 1. Building binary
# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
# image under 20mb we need to remove all the build dependencies in the same "RUN" / layer.
#
# 1. install deps, clone and build.
# 2. strip binaries.
# 3. Purge all dependencies and other unrelated packages, including build directory.
# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
# image under 20mb we need to remove all the build dependencies in the same "RUN" / layer.
#
# 1. install deps, clone and build.
# 2. strip binaries.
# 3. Purge all dependencies and other unrelated packages, including build directory.
RUN apk update \
&& apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl miniupnpc-dev git \
&& mkdir -p /tmp/build \
&& cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \
&& cd i2pd \
&& if [ -n "${GIT_TAG}" ]; then git checkout tags/${GIT_TAG}; fi \
&& make -j$(nproc) USE_UPNP=yes \
&& make USE_UPNP=yes \
&& cp -R contrib/certificates /i2pd_certificates \
&& mkdir -p /usr/local/bin \
&& mv i2pd /usr/local/bin \
@@ -59,9 +45,6 @@ RUN apk update \
# 2. Adding required libraries to run i2pd to ensure it will run.
RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl miniupnpc musl-utils libstdc++
# 3. Copy preconfigured config file and entrypoint
COPY i2pd-docker.conf "$DATA_DIR/i2pd.conf"
RUN chown i2pd:nobody "$DATA_DIR/i2pd.conf"
COPY entrypoint.sh /entrypoint.sh
RUN chmod a+x /entrypoint.sh

View File

@@ -1,52 +0,0 @@
## Preconfigured i2pd configuration file for a Docker container
## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/
## for more options you can use in this file.
## Note that for exposing ports outside of container you need to bind all services to 0.0.0.0
log = file
loglevel = none
ipv4 = true
ipv6 = false
# bandwidth = L
# notransit = false
# floodfill = false
[ntcp2]
enabled = true
published = true
[ssu2]
enabled = true
published = true
[http]
enabled = true
address = 0.0.0.0
port = 7070
[httpproxy]
enabled = true
address = 0.0.0.0
port = 4444
[socksproxy]
enabled = true
address = 0.0.0.0
port = 4447
[sam]
enabled = true
address = 0.0.0.0
port = 7656
[upnp]
enabled = false
[reseed]
verify = true
[limits]
# transittunnels = 2500

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,29 @@
`xgettext` command for extracting translation
---
```
xgettext --omit-header -ctr: -ktr -kntr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp
```
Regex for transforming gettext translations to our format:
---
```
in: ^(\"|#[:.,]|msgctxt)(.*)$\n
out: <to empty line>
```
```
in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\n(msgstr\[1\]\ \"(.*)\"\n)?(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)?
out: #{"$2", {"$3", "$5", "$7", "$9", "$11"}},\n
```
```
in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n
out: {"$1", "$2"},\n
```
```
in: \n\n
out: \n
```
`xgettext` command for extracting translation
---
```
xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp
```
Regex for transforming gettext translations to our format:
---
```
in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(.*)\"\n(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)?
out: #{"$2", {"$3", "$4", "$6", "$8", "$10"}},\n
```
```
in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n
out: {"$1", "$2"},\n
```
```
in: ^#[:.](.*)$\n
out: <to empty line>
```
```
in: \n\n
out: \n
```

View File

@@ -19,7 +19,7 @@
## Default: ~/.i2pd/certificates or /var/lib/i2pd/certificates
# certsdir = /var/lib/i2pd/certificates
## Where to write pidfile (default: /run/i2pd.pid, not used in Windows)
## Where to write pidfile (default: i2pd.pid, not used in Windows)
# pidfile = /run/i2pd.pid
## Logging configuration section
@@ -31,16 +31,15 @@
## * file - log entries to a file
## * syslog - use syslog, see man 3 syslog
# log = file
## Path to logfile (default: autodetect)
## Path to logfile (default - autodetect)
# logfile = /var/log/i2pd/i2pd.log
## Log messages above this level (debug, info, *warn, error, critical, none)
## Log messages above this level (debug, info, *warn, error, none)
## If you set it to none, logging will be disabled
# loglevel = warn
## Write full CLF-formatted date and time to log (default: write only time)
# logclftime = true
## Daemon mode. Router will go to background after start. Ignored on Windows
## (default: true)
# daemon = true
## Specify a family, router belongs to (default - none)
@@ -71,97 +70,74 @@
## don't just uncomment this
# port = 4567
## Enable communication through ipv4 (default: true)
## Enable communication through ipv4
ipv4 = true
## Enable communication through ipv6 (default: false)
## Enable communication through ipv6
ipv6 = false
## Enable SSU transport (default = true)
# ssu = true
## Bandwidth configuration
## L limit bandwidth to 32 KB/sec, O - to 256 KB/sec, P - to 2048 KB/sec,
## L limit bandwidth to 32KBs/sec, O - to 256KBs/sec, P - to 2048KBs/sec,
## X - unlimited
## Default is L (regular node) and X if floodfill mode enabled.
## If you want to share more bandwidth without floodfill mode, uncomment
## that line and adjust value to your possibilities. Value can be set to
## integer in kilobytes, it will apply that limit and flag will be used
## from next upper limit (example: if you set 4096 flag will be X, but real
## limit will be 4096 KB/s). Same can be done when floodfill mode is used,
## but keep in mind that low values may be negatively evaluated by Java
## router algorithms.
## Default is L (regular node) and X if floodfill mode enabled. If you want to
## share more bandwidth without floodfill mode, uncomment that line and adjust
## value to your possibilities
# bandwidth = L
## Max % of bandwidth limit for transit. 0-100 (default: 100)
## Max % of bandwidth limit for transit. 0-100. 100 by default
# share = 100
## Router will not accept transit tunnels, disabling transit traffic completely
## (default: false)
## (default = false)
# notransit = true
## Router will be floodfill (default: false)
## Router will be floodfill
## Note: that mode uses much more network connections and CPU!
# floodfill = true
[ntcp2]
## Enable NTCP2 transport (default: true)
# enabled = true
## Publish address in RouterInfo (default: true)
# published = true
## Port for incoming connections (default is global port option value)
# port = 4567
[ssu2]
## Enable SSU2 transport (default: true)
# enabled = true
## Publish address in RouterInfo (default: true)
# published = true
## Port for incoming connections (default is global port option value)
# port = 4567
[http]
## Web Console settings
## Enable the Web Console (default: true)
## Uncomment and set to 'false' to disable Web Console
# enabled = true
## Address and port service will listen on (default: 127.0.0.1:7070)
# address = 127.0.0.1
# port = 7070
## Path to web console (default: /)
## Address and port service will listen on
address = 127.0.0.1
port = 7070
## Path to web console, default "/"
# webroot = /
## Enable Web Console authentication (default: false)
## You should not use Web Console via public networks without additional encryption.
## HTTP authentication is not encryption layer!
## Uncomment following lines to enable Web Console authentication
# auth = true
# user = i2pd
# pass = changeme
## Select webconsole language
## Currently supported english (default), afrikaans, armenian, chinese, czech, french,
## german, italian, polish, portuguese, russian, spanish, turkish, turkmen, ukrainian
## and uzbek languages
## Currently supported english (default), afrikaans, armenian, french, german,
## russian, turkmen, ukrainian and uzbek languages
# lang = english
[httpproxy]
## Enable the HTTP proxy (default: true)
## Uncomment and set to 'false' to disable HTTP Proxy
# enabled = true
## Address and port service will listen on (default: 127.0.0.1:4444)
# address = 127.0.0.1
# port = 4444
## Optional keys file for proxy local destination (default: http-proxy-keys.dat)
## Address and port service will listen on
address = 127.0.0.1
port = 4444
## Optional keys file for proxy local destination
# keys = http-proxy-keys.dat
## Enable address helper for adding .i2p domains with "jump URLs" (default: true)
## You should disable this feature if your i2pd HTTP Proxy is public,
## because anyone could spoof the short domain via addresshelper and forward other users to phishing links
# addresshelper = true
## Address of a proxy server inside I2P, which is used to visit regular Internet
# outproxy = http://false.i2p
## httpproxy section also accepts I2CP parameters, like "inbound.length" etc.
[socksproxy]
## Enable the SOCKS proxy (default: true)
## Uncomment and set to 'false' to disable SOCKS Proxy
# enabled = true
## Address and port service will listen on (default: 127.0.0.1:4447)
# address = 127.0.0.1
# port = 4447
## Optional keys file for proxy local destination (default: socks-proxy-keys.dat)
## Address and port service will listen on
address = 127.0.0.1
port = 4447
## Optional keys file for proxy local destination
# keys = socks-proxy-keys.dat
## Socks outproxy. Example below is set to use Tor for all connections except i2p
## Enable using of SOCKS outproxy (works only with SOCKS4, default: false)
## Uncomment and set to 'true' to enable using of SOCKS outproxy
# outproxy.enabled = false
## Address and port of outproxy
# outproxy = 127.0.0.1
@@ -169,34 +145,33 @@ ipv6 = false
## socksproxy section also accepts I2CP parameters, like "inbound.length" etc.
[sam]
## Enable the SAM bridge (default: true)
# enabled = false
## Address and ports service will listen on (default: 127.0.0.1:7656, udp: 7655)
## Comment or set to 'false' to disable SAM Bridge
enabled = true
## Address and port service will listen on
# address = 127.0.0.1
# port = 7656
# portudp = 7655
[bob]
## Enable the BOB command channel (default: false)
## Uncomment and set to 'true' to enable BOB command channel
# enabled = false
## Address and port service will listen on (default: 127.0.0.1:2827)
## Address and port service will listen on
# address = 127.0.0.1
# port = 2827
[i2cp]
## Enable the I2CP protocol (default: false)
## Uncomment and set to 'true' to enable I2CP protocol
# enabled = false
## Address and port service will listen on (default: 127.0.0.1:7654)
## Address and port service will listen on
# address = 127.0.0.1
# port = 7654
[i2pcontrol]
## Enable the I2PControl protocol (default: false)
## Uncomment and set to 'true' to enable I2PControl protocol
# enabled = false
## Address and port service will listen on (default: 127.0.0.1:7650)
## Address and port service will listen on
# address = 127.0.0.1
# port = 7650
## Authentication password (default: itoopie)
## Authentication password. "itoopie" by default
# password = itoopie
[precomputation]
@@ -207,11 +182,11 @@ ipv6 = false
[upnp]
## Enable or disable UPnP: automatic port forwarding (enabled by default in WINDOWS, ANDROID)
# enabled = false
## Name i2pd appears in UPnP forwardings list (default: I2Pd)
## Name i2pd appears in UPnP forwardings list (default = I2Pd)
# name = I2Pd
[meshnets]
## Enable connectivity over the Yggdrasil network (default: false)
## Enable connectivity over the Yggdrasil network
# yggdrasil = false
## You can bind address from your Yggdrasil subnet 300::/64
## The address must first be added to the network interface
@@ -219,7 +194,7 @@ ipv6 = false
[reseed]
## Options for bootstrapping into I2P network, aka reseeding
## Enable reseed data verification (default: true)
## Enable or disable reseed data verification.
verify = true
## URLs to request reseed data from, separated by comma
## Default: "mainline" I2P Network reseeds
@@ -235,7 +210,7 @@ verify = true
## If you run i2pd behind a proxy server, set proxy server for reseeding here
## Should be http://address:port or socks://address:port
# proxy = http://127.0.0.1:8118
## Minimum number of known routers, below which i2pd triggers reseeding (default: 25)
## Minimum number of known routers, below which i2pd triggers reseeding. 25 by default
# threshold = 25
[addressbook]
@@ -246,22 +221,21 @@ verify = true
# subscriptions = http://reg.i2p/hosts.txt,http://identiguy.i2p/hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt
[limits]
## Maximum active transit sessions (default: 5000)
## This value is doubled if floodfill mode is enabled!
# transittunnels = 5000
## Maximum active transit sessions (default:2500)
# transittunnels = 2500
## Limit number of open file descriptors (0 - use system limit)
# openfiles = 0
## Maximum size of corefile in Kb (0 - use system limit)
# coresize = 0
[trust]
## Enable explicit trust options. (default: false)
## Enable explicit trust options. false by default
# enabled = true
## Make direct I2P connections only to routers in specified Family.
# family = MyFamily
## Make direct I2P connections only to routers specified here. Comma separated list of base64 identities.
# routers =
## Should we hide our router from other routers? (default: false)
## Should we hide our router from other routers? false by default
# hidden = true
[exploratory]
@@ -280,6 +254,8 @@ verify = true
[cpuext]
## Use CPU AES-NI instructions set when work with cryptography when available (default: true)
# aesni = true
## Force usage of CPU instructions set, even if they not found (default: false)
## Use CPU AVX instructions set when work with cryptography when available (default: true)
# avx = true
## Force usage of CPU instructions set, even if they not found
## DO NOT TOUCH that option if you really don't know what are you doing!
# force = false

View File

@@ -29,7 +29,7 @@ SendSIGKILL=yes
#TimeoutStopSec=10m
# If you have problems with hanging i2pd, you can try increase this
LimitNOFILE=8192
LimitNOFILE=4096
# To enable write of coredump uncomment this
#LimitCORE=infinity

View File

@@ -1,7 +1,7 @@
%define git_hash %(git rev-parse HEAD | cut -c -7)
Name: i2pd-git
Version: 2.49.0
Version: 2.42.1
Release: git%{git_hash}%{?dist}
Summary: I2P router written in C++
Conflicts: i2pd
@@ -28,11 +28,9 @@ Requires: logrotate
Requires: systemd
Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
%description
C++ implementation of I2P.
%prep
%setup -q -n i2pd-openssl
@@ -40,56 +38,78 @@ C++ implementation of I2P.
%build
cd build
%if 0%{?rhel} == 7
%cmake3 \
%cmake3 \
-DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \
-DWITH_HARDENING=ON \
-DBUILD_SHARED_LIBS:BOOL=OFF
%else
%cmake \
%cmake \
-DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \
-DWITH_HARDENING=ON \
%if 0%{?fedora} > 29
%if 0%{?fedora} > 29
-DBUILD_SHARED_LIBS:BOOL=OFF \
.
%else
%else
-DBUILD_SHARED_LIBS:BOOL=OFF
%endif
%endif
%endif
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?mageia} > 7
pushd build
%endif
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?fedora} >= 35
%if 0%{?fedora} < 37
pushd redhat-linux-build
%endif
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia} > 7
pushd build
%endif
make %{?_smp_mflags}
%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7
popd
%if 0%{?rhel} == 9
popd
%endif
%if 0%{?fedora} >= 33
%if 0%{?fedora} < 37
popd
%endif
%endif
%if 0%{?mageia} > 7
popd
%endif
%install
pushd build
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?mageia}
pushd build
%endif
%if 0%{?fedora} >= 35
%if 0%{?fedora} < 37
pushd redhat-linux-build
%endif
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia}
pushd build
%endif
chrpath -d i2pd
@@ -144,33 +164,6 @@ getent passwd i2pd >/dev/null || \
%changelog
* Mon Sep 18 2023 orignal <orignal@i2pmail.org> - 2.49.0
- update to 2.49.0
* Mon Jun 12 2023 orignal <orignal@i2pmail.org> - 2.48.0
- update to 2.48.0
* Sat Mar 11 2023 orignal <orignal@i2pmail.org> - 2.47.0
- update to 2.47.0
* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
- update to 2.46.1
* Wed Feb 15 2023 orignal <orignal@i2pmail.org> - 2.46.0
- update to 2.46.0
* Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
* Tue Jan 3 2023 orignal <orignal@i2pmail.org> - 2.45.0
- update to 2.45.0
* Sun Nov 20 2022 orignal <orignal@i2pmail.org> - 2.44.0
- update to 2.44.0
* Mon Aug 22 2022 orignal <orignal@i2pmail.org> - 2.43.0
- update to 2.43.0
* Tue May 24 2022 r4sas <r4sas@i2pmail.org> - 2.42.1
- update to 2.42.1

View File

@@ -1,5 +1,5 @@
Name: i2pd
Version: 2.49.0
Version: 2.42.1
Release: 1%{?dist}
Summary: I2P router written in C++
Conflicts: i2pd-git
@@ -26,11 +26,9 @@ Requires: logrotate
Requires: systemd
Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
%description
C++ implementation of I2P.
%prep
%setup -q
@@ -38,56 +36,77 @@ C++ implementation of I2P.
%build
cd build
%if 0%{?rhel} == 7
%cmake3 \
%cmake3 \
-DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \
-DWITH_HARDENING=ON \
-DBUILD_SHARED_LIBS:BOOL=OFF
%else
%cmake \
%cmake \
-DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \
-DWITH_HARDENING=ON \
%if 0%{?fedora} > 29
%if 0%{?fedora} > 29
-DBUILD_SHARED_LIBS:BOOL=OFF \
.
%else
%else
-DBUILD_SHARED_LIBS:BOOL=OFF
%endif
%endif
%endif
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?mageia} > 7
pushd build
%endif
%if 0%{?fedora} >= 35
%if 0%{?fedora} < 37
pushd redhat-linux-build
%endif
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia} > 7
pushd build
%endif
make %{?_smp_mflags}
%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7
popd
%if 0%{?rhel} == 9
popd
%endif
%if 0%{?fedora} >= 33
%if 0%{?fedora} < 37
popd
%endif
%endif
%if 0%{?mageia} > 7
popd
%endif
%install
pushd build
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?mageia}
pushd build
%endif
%if 0%{?fedora} >= 35
%if 0%{?fedora} < 37
pushd redhat-linux-build
%endif
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia}
pushd build
%endif
chrpath -d i2pd
@@ -142,33 +161,6 @@ getent passwd i2pd >/dev/null || \
%changelog
* Mon Sep 18 2023 orignal <orignal@i2pmail.org> - 2.49.0
- update to 2.49.0
* Mon Jun 12 2023 orignal <orignal@i2pmail.org> - 2.48.0
- update to 2.48.0
* Sat Mar 11 2023 orignal <orignal@i2pmail.org> - 2.47.0
- update to 2.47.0
* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
- update to 2.46.1
* Wed Feb 15 2023 orignal <orignal@i2pmail.org> - 2.46.0
- update to 2.46.0
* Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
* Tue Jan 3 2023 orignal <orignal@i2pmail.org> - 2.45.0
- update to 2.45.0
* Sun Nov 20 2022 orignal <orignal@i2pmail.org> - 2.44.0
- update to 2.44.0
* Mon Aug 22 2022 orignal <orignal@i2pmail.org> - 2.43.0
- update to 2.43.0
* Tue May 24 2022 r4sas <r4sas@i2pmail.org> - 2.42.1
- update to 2.42.1

View File

@@ -1,293 +1,293 @@
/*
* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*
******************************************************************
*
* This is style sheet for webconsole, with @media selectors for adaptive
* view on desktop and mobile devices, respecting preferred user's color
* scheme used in system/browser.
*
* Minified copy of that style sheet is bundled inside i2pd sources.
*/
:root {
--main-bg-color: #fafafa;
--main-text-color: #103456;
--main-link-color: #894c84;
--main-link-hover-color: #fafafa;
}
@media (prefers-color-scheme: dark) {
:root {
--main-bg-color: #242424;
--main-text-color: #17ab5c;
--main-link-color: #bf64b7;
--main-link-hover-color: #000000;
}
}
body {
font: 100%/1.5em sans-serif;
margin: 0;
padding: 1.5em;
background: var(--main-bg-color);
color: var(--main-text-color);
}
a, .slide label {
text-decoration: none;
color: var(--main-link-color);
}
a:hover, a.button.selected, .slide label:hover, button[type=submit]:hover {
color: var(--main-link-hover-color);
background: var(--main-link-color);
}
a.button {
appearance: button;
text-decoration: none;
padding: 0 5px;
border: 1px solid var(--main-link-color);
}
.header {
font-size: 2.5em;
text-align: center;
margin: 1em 0;
color: var(--main-link-color);
}
.wrapper {
margin: 0 auto;
padding: 1em;
max-width: 64em;
}
.menu {
display: block;
float: left;
overflow: hidden;
padding: 4px;
max-width: 12em;
white-space: nowrap;
text-overflow: ellipsis;
}
.listitem {
display: block;
font-family: monospace;
font-size: 1.2em;
white-space: nowrap;
}
.tableitem {
font-family: monospace;
font-size: 1.2em;
white-space: nowrap;
}
.content {
float: left;
font-size: 1em;
margin-left: 2em;
padding: 4px;
max-width: 50em;
overflow: auto;
}
.tunnel.established {
color: #56B734;
}
.tunnel.expiring {
color: #D3AE3F;
}
.tunnel.failed {
color: #D33F3F;
}
.tunnel.building {
color: #434343;
}
caption {
font-size: 1.5em;
text-align: center;
color: var(--main-link-color);
}
table {
display: table;
border-collapse: collapse;
text-align: center;
}
table.extaddr {
text-align: left;
}
table.services {
width: 100%;
}
textarea {
background-color: var(--main-bg-color);
color: var(--main-text-color);
word-break: break-all;
}
.streamdest {
width: 120px;
max-width: 240px;
overflow: hidden;
text-overflow: ellipsis;
}
.slide div.slidecontent, .slide [type="checkbox"] {
display: none;
}
.slide [type="checkbox"]:checked ~ div.slidecontent {
display: block;
margin-top: 0;
padding: 0;
}
.disabled {
color: #D33F3F;
}
.enabled {
color: #56B734;
}
button[type=submit] {
background-color: transparent;
color: var(--main-link-color);
text-decoration: none;
padding: 5px;
border: 1px solid var(--main-link-color);
font-size: 14px;
}
input, select, select option {
background-color: var(--main-bg-color);
color: var(--main-link-color);
padding: 5px;
border: 1px solid var(--main-link-color);
font-size: 14px;
}
input:focus, select:focus, select option:focus {
outline: none;
}
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
}
@media screen and (max-width: 1150px) { /* adaptive style */
.wrapper {
max-width: 58em;
}
.content {
max-width: 40em;
}
}
@media screen and (max-width: 980px) {
body {
font: 100%/1.2em sans-serif;
padding: 1.2em 0 0 0;
}
.menu {
width: 100%;
max-width: unset;
display: block;
float: none;
position: unset;
font-size: 16px;
text-align: center;
}
.menu a, .commands a {
display: inline-block;
padding: 4px;
}
.content {
float: none;
margin-left: unset;
margin-top: 16px;
max-width: 100%;
width: 100%;
text-align: center;
}
a, .slide label {
display: block;
}
.header {
margin: unset;
font-size: 1.5em;
}
small {
display: block
}
a.button {
appearance: button;
text-decoration: none;
margin-top: 10px;
padding: 6px;
border: 2px solid var(--main-link-color);
border-radius: 5px;
width: -webkit-fill-available;
}
input, select {
width: 35%;
text-align: center;
padding: 5px;
border: 2px solid var(--main-link-color);
border-radius: 5px;
font-size: 18px;
}
table.extaddr {
margin: auto;
text-align: unset;
}
textarea {
width: -webkit-fill-available;
height: auto;
padding: 5px;
border: 2px solid var(--main-link-color);
border-radius: 5px;
font-size: 12px;
}
button[type=submit] {
padding: 5px 15px;
background: transparent;
border: 2px solid var(--main-link-color);
cursor: pointer;
-webkit-border-radius: 5px;
border-radius: 5px;
position: relative;
height: 36px;
display: -webkit-inline-box;
margin-top: 10px;
}
}
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*
******************************************************************
*
* This is style sheet for webconsole, with @media selectors for adaptive
* view on desktop and mobile devices, respecting preferred user's color
* scheme used in system/browser.
*
* Minified copy of that style sheet is bundled inside i2pd sources.
*/
:root {
--main-bg-color: #fafafa;
--main-text-color: #103456;
--main-link-color: #894c84;
--main-link-hover-color: #fafafa;
}
@media (prefers-color-scheme: dark) {
:root {
--main-bg-color: #242424;
--main-text-color: #17ab5c;
--main-link-color: #bf64b7;
--main-link-hover-color: #000000;
}
}
body {
font: 100%/1.5em sans-serif;
margin: 0;
padding: 1.5em;
background: var(--main-bg-color);
color: var(--main-text-color);
}
a, .slide label {
text-decoration: none;
color: var(--main-link-color);
}
a:hover, .slide label:hover, button[type=submit]:hover {
color: var(--main-link-hover-color);
background: var(--main-link-color);
}
a.button {
appearance: button;
text-decoration: none;
padding: 0 5px;
border: 1px solid var(--main-link-color);
}
.header {
font-size: 2.5em;
text-align: center;
margin: 1em 0;
color: var(--main-link-color);
}
.wrapper {
margin: 0 auto;
padding: 1em;
max-width: 64em;
}
.menu {
display: block;
float: left;
overflow: hidden;
padding: 4px;
max-width: 12em;
white-space: nowrap;
text-overflow: ellipsis;
}
.listitem {
display: block;
font-family: monospace;
font-size: 1.2em;
white-space: nowrap;
}
.tableitem {
font-family: monospace;
font-size: 1.2em;
white-space: nowrap;
}
.content {
float: left;
font-size: 1em;
margin-left: 2em;
padding: 4px;
max-width: 50em;
overflow: auto;
}
.tunnel.established {
color: #56B734;
}
.tunnel.expiring {
color: #D3AE3F;
}
.tunnel.failed {
color: #D33F3F;
}
.tunnel.building {
color: #434343;
}
caption {
font-size: 1.5em;
text-align: center;
color: var(--main-link-color);
}
table {
display: table;
border-collapse: collapse;
text-align: center;
}
table.extaddr {
text-align: left;
}
table.services {
width: 100%;
}
textarea {
background-color: var(--main-bg-color);
color: var(--main-text-color);
word-break: break-all;
}
.streamdest {
width: 120px;
max-width: 240px;
overflow: hidden;
text-overflow: ellipsis;
}
.slide div.slidecontent, .slide [type="checkbox"] {
display: none;
}
.slide [type="checkbox"]:checked ~ div.slidecontent {
display: block;
margin-top: 0;
padding: 0;
}
.disabled {
color: #D33F3F;
}
.enabled {
color: #56B734;
}
button[type=submit] {
background-color: transparent;
color: var(--main-link-color);
text-decoration: none;
padding: 5px;
border: 1px solid var(--main-link-color);
font-size: 14px;
}
input, select, select option {
background-color: var(--main-bg-color);
color: var(--main-link-color);
padding: 5px;
border: 1px solid var(--main-link-color);
font-size: 14px;
}
input:focus, select:focus, select option:focus {
outline: none;
}
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
}
@media screen and (max-width: 1150px) { /* adaptive style */
.wrapper {
max-width: 58em;
}
.content {
max-width: 40em;
}
}
@media screen and (max-width: 980px) {
body {
font: 100%/1.2em sans-serif;
padding: 1.2em 0 0 0;
}
.menu {
width: 100%;
max-width: unset;
display: block;
float: none;
position: unset;
font-size: 16px;
text-align: center;
}
.menu a, .commands a {
display: inline-block;
padding: 4px;
}
.content {
float: none;
margin-left: unset;
margin-top: 16px;
max-width: 100%;
width: 100%;
text-align: center;
}
a, .slide label {
display: block;
}
.header {
margin: unset;
font-size: 1.5em;
}
small {
display: block
}
a.button {
appearance: button;
text-decoration: none;
margin-top: 10px;
padding: 6px;
border: 2px solid var(--main-link-color);
border-radius: 5px;
width: -webkit-fill-available;
}
input, select {
width: 35%;
text-align: center;
padding: 5px;
border: 2px solid var(--main-link-color);
border-radius: 5px;
font-size: 18px;
}
table.extaddr {
margin: auto;
text-align: unset;
}
textarea {
width: -webkit-fill-available;
height: auto;
padding: 5px;
border: 2px solid var(--main-link-color);
border-radius: 5px;
font-size: 12px;
}
button[type=submit] {
padding: 5px 15px;
background: transparent;
border: 2px solid var(--main-link-color);
cursor: pointer;
-webkit-border-radius: 5px;
border-radius: 5px;
position: relative;
height: 36px;
display: -webkit-inline-box;
margin-top: 10px;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2023, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,6 +31,7 @@
#include "Crypto.h"
#include "UPnP.h"
#include "Timestamp.h"
#include "util.h"
#include "I18N.h"
namespace i2p
@@ -150,35 +151,132 @@ namespace util
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
bool avx; i2p::config::GetOption("cpuext.avx", avx);
bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt);
bool ssu; i2p::config::GetOption("ssu", ssu);
if (!ssu && i2p::config::IsDefault ("precomputation.elgamal"))
precomputation = false; // we don't elgamal table if no ssu, unless it's specified explicitly
i2p::crypto::InitCrypto (precomputation, aesni, forceCpuExt);
i2p::transport::InitAddressFromIface (); // get address4/6 from interfaces
i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt);
int netID; i2p::config::GetOption("netid", netID);
i2p::context.SetNetID (netID);
i2p::context.Init ();
i2p::transport::InitTransports ();
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
if (isFloodfill)
// ifname -> address
std::string ifname; i2p::config::GetOption("ifname", ifname);
if (ipv4 && i2p::config::IsDefault ("address4"))
{
LogPrint(eLogInfo, "Daemon: Router configured as floodfill");
i2p::context.SetFloodfill (true);
std::string ifname4; i2p::config::GetOption("ifname4", ifname4);
if (!ifname4.empty ())
i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname4, false).to_string ()); // v4
else if (!ifname.empty ())
i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname, false).to_string ()); // v4
}
if (ipv6 && i2p::config::IsDefault ("address6"))
{
std::string ifname6; i2p::config::GetOption("ifname6", ifname6);
if (!ifname6.empty ())
i2p::config::SetOption ("address6", i2p::util::net::GetInterfaceAddress(ifname6, true).to_string ()); // v6
else if (!ifname.empty ())
i2p::config::SetOption ("address6", i2p::util::net::GetInterfaceAddress(ifname, true).to_string ()); // v6
}
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
boost::asio::ip::address_v6 yggaddr;
if (ygg)
{
std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress);
if (!yggaddress.empty ())
{
yggaddr = boost::asio::ip::address_v6::from_string (yggaddress);
if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) ||
!i2p::util::net::IsLocalAddress (yggaddr))
{
LogPrint(eLogWarning, "Daemon: Can't find Yggdrasil address ", yggaddress);
ygg = false;
}
}
else
{
yggaddr = i2p::util::net::GetYggdrasilAddress ();
if (yggaddr.is_unspecified ())
{
LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled");
ygg = false;
}
}
}
uint16_t port; i2p::config::GetOption("port", port);
if (!i2p::config::IsDefault("port"))
{
LogPrint(eLogInfo, "Daemon: Accepting incoming connections at port ", port);
i2p::context.UpdatePort (port);
}
i2p::context.SetSupportsV6 (ipv6);
i2p::context.SetSupportsV4 (ipv4);
i2p::context.SetSupportsMesh (ygg, yggaddr);
i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
if (ntcp2)
{
bool published; i2p::config::GetOption("ntcp2.published", published);
if (published)
{
std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy);
if (!ntcp2proxy.empty ()) published = false;
}
if (published)
{
uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port);
if (!ntcp2port) ntcp2port = port; // use standard port
i2p::context.PublishNTCP2Address (ntcp2port, true, ipv4, ipv6, false); // publish
if (ipv6)
{
std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr);
auto addr = boost::asio::ip::address_v6::from_string (ipv6Addr);
if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ())
i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured
}
}
else
i2p::context.PublishNTCP2Address (port, false, ipv4, ipv6, false); // unpublish
}
if (ygg)
{
i2p::context.PublishNTCP2Address (port, true, false, false, true);
i2p::context.UpdateNTCP2V6Address (yggaddr);
if (!ipv4 && !ipv6)
i2p::context.SetStatus (eRouterStatusMesh);
}
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
if (ssu2)
{
bool published; i2p::config::GetOption("ssu2.published", published);
if (published)
{
uint16_t ssu2port; i2p::config::GetOption("ssu2.port", ssu2port);
i2p::context.PublishSSU2Address (ssu2port, true, ipv4, ipv6); // publish
}
else
i2p::context.PublishSSU2Address (0, false, ipv4, ipv6); // unpublish
}
else
i2p::context.SetFloodfill (false);
bool transit; i2p::config::GetOption("notransit", transit);
i2p::context.SetAcceptsTunnels (!transit);
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
if (isFloodfill && i2p::config::IsDefault ("limits.transittunnels"))
transitTunnels *= 2; // double default number of transit tunnels for floodfill
i2p::tunnel::tunnels.SetMaxNumTransitTunnels (transitTunnels);
SetMaxNumTransitTunnels (transitTunnels);
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
if (isFloodfill) {
LogPrint(eLogInfo, "Daemon: Router configured as floodfill");
i2p::context.SetFloodfill (true);
}
else
{
i2p::context.SetFloodfill (false);
}
/* this section also honors 'floodfill' flag, if set above */
std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth);
@@ -268,7 +366,7 @@ namespace util
if (hidden)
{
LogPrint(eLogInfo, "Daemon: Hidden mode enabled");
i2p::context.SetHidden(true);
i2p::data::netdb.SetHidden(true);
}
std::string httpLang; i2p::config::GetOption("http.lang", httpLang);
@@ -298,18 +396,19 @@ namespace util
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
bool ssu; i2p::config::GetOption("ssu", ssu);
bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
LogPrint(eLogInfo, "Daemon: Starting Transports");
if(!ssu2) LogPrint(eLogInfo, "Daemon: SSU2 disabled");
if(!ssu) LogPrint(eLogInfo, "Daemon: SSU disabled");
if(!ntcp2) LogPrint(eLogInfo, "Daemon: NTCP2 disabled");
i2p::transport::transports.SetCheckReserved(checkInReserved);
i2p::transport::transports.Start(ntcp2, ssu2);
if (i2p::transport::transports.IsBoundSSU2() || i2p::transport::transports.IsBoundNTCP2())
i2p::transport::transports.Start(ntcp2, ssu, ssu2);
if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
LogPrint(eLogInfo, "Daemon: Transports started");
else
{
LogPrint(eLogCritical, "Daemon: Failed to start Transports");
LogPrint(eLogError, "Daemon: Failed to start Transports");
/** shut down netdb right away */
i2p::transport::transports.Stop();
i2p::data::netdb.Stop();
@@ -324,21 +423,23 @@ namespace util
try
{
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
d.httpServer->SetDaemonStop (std::bind (Daemon_Singleton::stop, this));
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
d.httpServer->SetDaemonGracefulTimer (std::bind (gracefulShutdownInterval, this));
#endif
d.httpServer->Start();
}
catch (std::exception& ex)
{
LogPrint (eLogCritical, "Daemon: Failed to start Webconsole: ", ex.what ());
LogPrint (eLogError, "Daemon: Failed to start Webconsole: ", ex.what ());
ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ());
}
}
LogPrint(eLogInfo, "Daemon: Starting Tunnels");
i2p::tunnel::tunnels.Start();
LogPrint(eLogInfo, "Daemon: Starting Router context");
i2p::context.Start();
LogPrint(eLogInfo, "Daemon: Starting Client");
i2p::client::context.Start ();
@@ -355,7 +456,7 @@ namespace util
}
catch (std::exception& ex)
{
LogPrint (eLogCritical, "Daemon: Failed to start I2PControl: ", ex.what ());
LogPrint (eLogError, "Daemon: Failed to start I2PControl: ", ex.what ());
ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
}
}
@@ -367,8 +468,6 @@ namespace util
LogPrint(eLogInfo, "Daemon: Shutting down");
LogPrint(eLogInfo, "Daemon: Stopping Client");
i2p::client::context.Stop();
LogPrint(eLogInfo, "Daemon: Stopping Router context");
i2p::context.Stop();
LogPrint(eLogInfo, "Daemon: Stopping Tunnels");
i2p::tunnel::tunnels.Stop();

View File

@@ -75,14 +75,17 @@ namespace util
return instance;
}
bool init(int argc, char* argv[]);
bool start();
bool stop();
bool init (int argc, char* argv[]);
bool start ();
bool stop ();
void run ();
bool isGraceful;
void SetIsGraceful (bool state) { m_isGraceful = state; };
const bool GetIsGraceful () { return m_isGraceful; };
DaemonWin32 ():isGraceful(false) {}
private:
bool m_isGraceful;
};
#elif (defined(ANDROID) && !defined(ANDROID_BINARY))
#define Daemon i2p::util::DaemonAndroid::Instance()
@@ -109,8 +112,8 @@ namespace util
return instance;
}
bool start();
bool stop();
bool start ();
bool stop ();
void run ();
private:

View File

@@ -24,7 +24,6 @@
#include "Tunnel.h"
#include "RouterContext.h"
#include "ClientContext.h"
#include "Transports.h"
void handle_signal(int sig)
{
@@ -55,14 +54,6 @@ void handle_signal(int sig)
case SIGPIPE:
LogPrint(eLogInfo, "SIGPIPE received");
break;
case SIGTSTP:
LogPrint(eLogInfo, "Daemon: Got SIGTSTP, disconnecting from network...");
i2p::transport::transports.SetOnline(false);
break;
case SIGCONT:
LogPrint(eLogInfo, "Daemon: Got SIGCONT, restoring connection to network...");
i2p::transport::transports.SetOnline(true);
break;
}
}
@@ -173,16 +164,13 @@ namespace i2p
ftruncate(pidFH, 0);
if (write(pidFH, pid, strlen(pid)) < 0)
{
LogPrint(eLogCritical, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno));
LogPrint(eLogError, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno));
std::cerr << "i2pd: Could not write pidfile " << pidfile << ": " << strerror(errno) << std::endl;
return false;
}
}
gracefulShutdownInterval = 0; // not specified
// handle signal TSTP
bool handleTSTP; i2p::config::GetOption("unix.handle_sigtstp", handleTSTP);
// Signal handler
struct sigaction sa;
sa.sa_handler = handle_signal;
@@ -194,11 +182,6 @@ namespace i2p
sigaction(SIGTERM, &sa, 0);
sigaction(SIGINT, &sa, 0);
sigaction(SIGPIPE, &sa, 0);
if (handleTSTP)
{
sigaction(SIGTSTP, &sa, 0);
sigaction(SIGCONT, &sa, 0);
}
return Daemon_Singleton::start();
}

View File

@@ -1,11 +1,13 @@
/*
* Copyright (c) 2013-2023, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifdef _WIN32
#include <thread>
#include <clocale>
#include "Config.h"
@@ -13,7 +15,6 @@
#include "util.h"
#include "Log.h"
#ifdef _WIN32
#include "Win32Service.h"
#ifdef WIN32_APP
#include <windows.h>
@@ -29,7 +30,7 @@ namespace util
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
//setlocale(LC_ALL, "Russian");
setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C");
i2p::log::SetThrowFunction ([](const std::string& s)
@@ -38,6 +39,9 @@ namespace util
}
);
i2p::win32::SetIsGraceful (std::bind (&DaemonWin32::SetIsGraceful, this, std::placeholders::_1));
i2p::win32::GetIsGraceful (std::bind (&DaemonWin32::GetIsGraceful, this));
if (!Daemon_Singleton::init(argc, argv))
return false;
@@ -45,9 +49,11 @@ namespace util
{
LogPrint(eLogDebug, "Daemon: running as service");
I2PService service((PSTR)SERVICE_NAME);
service.SetDaemonStart (std::bind (&DaemonWin32::start, this));
service.SetDaemonStop (std::bind (&DaemonWin32::stop, this));
if (!I2PService::Run(service))
{
LogPrint(eLogCritical, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
return false;
}
return false;
@@ -61,10 +67,10 @@ namespace util
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
//setlocale(LC_ALL, "Russian");
setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C");
#ifdef WIN32_APP
if (!i2p::win32::StartWin32App (isDaemon)) return false;
if (!i2p::win32::StartWin32App ()) return false;
#endif
bool ret = Daemon_Singleton::start();
if (ret && i2p::log::Logger().GetLogType() == eLogFile)

View File

@@ -14,17 +14,25 @@
// Use global placeholders from boost introduced when local_time.hpp is loaded
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/lexical_cast.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/lexical_cast.hpp>
#include "Crypto.h"
#include "FS.h"
#include "Log.h"
#include "Config.h"
#include "NetDb.hpp"
#include "Tunnel.h"
#include "RouterContext.h"
#include "Daemon.h"
#include "Tunnel.h"
#include "Timestamp.h"
#include "Transports.h"
#include "version.h"
#include "util.h"
#include "ClientContext.h"
#include "I2PControl.h"
namespace i2p
@@ -61,18 +69,44 @@ namespace client
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
m_MethodHandlers["RouterInfo"] = &I2PControlHandlers::RouterInfoHandler;
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
m_MethodHandlers["NetworkSetting"] = &I2PControlHandlers::NetworkSettingHandler;
m_MethodHandlers["ClientServicesInfo"] = &I2PControlHandlers::ClientServicesInfoHandler;
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
// I2PControl
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
// RouterInfo
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S;
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler;
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
// RouterManager
m_RouterManagerHandlers["Reseed"] = &I2PControlService::ReseedHandler;
m_RouterManagerHandlers["Shutdown"] = &I2PControlService::ShutdownHandler;
m_RouterManagerHandlers["ShutdownGraceful"] = &I2PControlService::ShutdownGracefulHandler;
// NetworkSetting
m_NetworkSettingHandlers["i2p.router.net.bw.in"] = &I2PControlService::InboundBandwidthLimit;
m_NetworkSettingHandlers["i2p.router.net.bw.out"] = &I2PControlService::OutboundBandwidthLimit;
// ClientServicesInfo
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
}
I2PControlService::~I2PControlService ()
@@ -246,6 +280,37 @@ namespace client
}
}
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, int value) const
{
ss << "\"" << name << "\":" << value;
}
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value, bool quotes) const
{
ss << "\"" << name << "\":";
if (value.length () > 0)
{
if (quotes)
ss << "\"" << value << "\"";
else
ss << value;
}
else
ss << "null";
}
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, double value) const
{
ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value;
}
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const
{
std::ostringstream buf;
boost::property_tree::write_json (buf, value, false);
ss << "\"" << name << "\":" << buf.str();
}
void I2PControlService::SendResponse (std::shared_ptr<ssl_socket> socket,
std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml)
{
@@ -331,6 +396,91 @@ namespace client
m_Tokens.clear ();
}
// RouterInfo
void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
bool first = true;
for (auto it = params.begin (); it != params.end (); it++)
{
LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first);
auto it1 = m_RouterInfoHandlers.find (it->first);
if (it1 != m_RouterInfoHandlers.end ())
{
if (!first) results << ",";
else first = false;
(this->*(it1->second))(results);
}
else
LogPrint (eLogError, "I2PControl: RouterInfo unknown request ", it->first);
}
}
void I2PControlService::UptimeHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.uptime", std::to_string (i2p::context.GetUptime ()*1000LL), false);
}
void I2PControlService::VersionHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.version", VERSION);
}
void I2PControlService::StatusHandler (std::ostringstream& results)
{
auto dest = i2p::client::context.GetSharedLocalDestination ();
InsertParam (results, "i2p.router.status", (dest && dest->IsReady ()) ? "1" : "0");
}
void I2PControlService::NetDbKnownPeersHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.netdb.knownpeers", i2p::data::netdb.GetNumRouters ());
}
void I2PControlService::NetDbActivePeersHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.netdb.activepeers", (int)i2p::transport::transports.GetPeers ().size ());
}
void I2PControlService::NetStatusHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.net.status", (int)i2p::context.GetStatus ());
}
void I2PControlService::TunnelsParticipatingHandler (std::ostringstream& results)
{
int transit = i2p::tunnel::tunnels.GetTransitTunnels ().size ();
InsertParam (results, "i2p.router.net.tunnels.participating", transit);
}
void I2PControlService::TunnelsSuccessRateHandler (std::ostringstream& results)
{
int rate = i2p::tunnel::tunnels.GetTunnelCreationSuccessRate ();
InsertParam (results, "i2p.router.net.tunnels.successrate", rate);
}
void I2PControlService::InboundBandwidth1S (std::ostringstream& results)
{
double bw = i2p::transport::transports.GetInBandwidth ();
InsertParam (results, "i2p.router.net.bw.inbound.1s", bw);
}
void I2PControlService::OutboundBandwidth1S (std::ostringstream& results)
{
double bw = i2p::transport::transports.GetOutBandwidth ();
InsertParam (results, "i2p.router.net.bw.outbound.1s", bw);
}
void I2PControlService::NetTotalReceivedBytes (std::ostringstream& results)
{
InsertParam (results, "i2p.router.net.total.received.bytes", (double)i2p::transport::transports.GetTotalReceivedBytes ());
}
void I2PControlService::NetTotalSentBytes (std::ostringstream& results)
{
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
}
// RouterManager
@@ -382,6 +532,37 @@ namespace client
i2p::data::netdb.Reseed ();
}
// network setting
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
for (auto it = params.begin (); it != params.end (); it++)
{
LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first);
auto it1 = m_NetworkSettingHandlers.find (it->first);
if (it1 != m_NetworkSettingHandlers.end ()) {
if (it != params.begin ()) results << ",";
(this->*(it1->second))(it->second.data (), results);
} else
LogPrint (eLogError, "I2PControl: NetworkSetting unknown request: ", it->first);
}
}
void I2PControlService::InboundBandwidthLimit (const std::string& value, std::ostringstream& results)
{
if (value != "null")
i2p::context.SetBandwidth (std::atoi(value.c_str()));
int bw = i2p::context.GetBandwidthLimit();
InsertParam (results, "i2p.router.net.bw.in", bw);
}
void I2PControlService::OutboundBandwidthLimit (const std::string& value, std::ostringstream& results)
{
if (value != "null")
i2p::context.SetBandwidth (std::atoi(value.c_str()));
int bw = i2p::context.GetBandwidthLimit();
InsertParam (results, "i2p.router.net.bw.out", bw);
}
// certificate
void I2PControlService::CreateCertificate (const char *crt_path, const char *key_path)
{
@@ -430,5 +611,178 @@ namespace client
}
EVP_PKEY_free (pkey);
}
// ClientServicesInfo
void I2PControlService::ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
for (auto it = params.begin (); it != params.end (); it++)
{
LogPrint (eLogDebug, "I2PControl: ClientServicesInfo request: ", it->first);
auto it1 = m_ClientServicesInfoHandlers.find (it->first);
if (it1 != m_ClientServicesInfoHandlers.end ())
{
if (it != params.begin ()) results << ",";
(this->*(it1->second))(results);
}
else
LogPrint (eLogError, "I2PControl: ClientServicesInfo unknown request ", it->first);
}
}
void I2PControlService::I2PTunnelInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
boost::property_tree::ptree client_tunnels, server_tunnels;
for (auto& it: i2p::client::context.GetClientTunnels ())
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
boost::property_tree::ptree ct;
ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
client_tunnels.add_child(it.second->GetName (), ct);
}
auto& serverTunnels = i2p::client::context.GetServerTunnels ();
if (!serverTunnels.empty ()) {
for (auto& it: serverTunnels)
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
boost::property_tree::ptree st;
st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
st.put("port", it.second->GetLocalPort ());
server_tunnels.add_child(it.second->GetName (), st);
}
}
auto& clientForwards = i2p::client::context.GetClientForwards ();
if (!clientForwards.empty ())
{
for (auto& it: clientForwards)
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
boost::property_tree::ptree ct;
ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
client_tunnels.add_child(it.second->GetName (), ct);
}
}
auto& serverForwards = i2p::client::context.GetServerForwards ();
if (!serverForwards.empty ())
{
for (auto& it: serverForwards)
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
boost::property_tree::ptree st;
st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
server_tunnels.add_child(it.second->GetName (), st);
}
}
pt.add_child("client", client_tunnels);
pt.add_child("server", server_tunnels);
InsertParam (results, "I2PTunnel", pt);
}
void I2PControlService::HTTPProxyInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto httpProxy = i2p::client::context.GetHttpProxy ();
if (httpProxy)
{
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
pt.put("enabled", true);
pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
}
else
pt.put("enabled", false);
InsertParam (results, "HTTPProxy", pt);
}
void I2PControlService::SOCKSInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto socksProxy = i2p::client::context.GetSocksProxy ();
if (socksProxy)
{
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
pt.put("enabled", true);
pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
}
else
pt.put("enabled", false);
InsertParam (results, "SOCKS", pt);
}
void I2PControlService::SAMInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto sam = i2p::client::context.GetSAMBridge ();
if (sam)
{
pt.put("enabled", true);
boost::property_tree::ptree sam_sessions;
for (auto& it: sam->GetSessions ())
{
boost::property_tree::ptree sam_session, sam_session_sockets;
auto& name = it.second->GetLocalDestination ()->GetNickname ();
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
sam_session.put("name", name);
sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
for (const auto& socket: sam->ListSockets(it.first))
{
boost::property_tree::ptree stream;
stream.put("type", socket->GetSocketType ());
stream.put("peer", socket->GetSocket ().remote_endpoint());
sam_session_sockets.push_back(std::make_pair("", stream));
}
sam_session.add_child("sockets", sam_session_sockets);
sam_sessions.add_child(it.first, sam_session);
}
pt.add_child("sessions", sam_sessions);
}
else
pt.put("enabled", false);
InsertParam (results, "SAM", pt);
}
void I2PControlService::BOBInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto bob = i2p::client::context.GetBOBCommandChannel ();
if (bob)
{
/* TODO more info */
pt.put("enabled", true);
}
else
pt.put("enabled", false);
InsertParam (results, "BOB", pt);
}
void I2PControlService::I2CPInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto i2cp = i2p::client::context.GetI2CPServer ();
if (i2cp)
{
/* TODO more info */
pt.put("enabled", true);
}
else
pt.put("enabled", false);
InsertParam (results, "I2CP", pt);
}
}
}

View File

@@ -20,7 +20,6 @@
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/property_tree/ptree.hpp>
#include "I2PControlHandlers.h"
namespace i2p
{
@@ -33,7 +32,7 @@ namespace client
const char I2P_CONTROL_CERTIFICATE_COMMON_NAME[] = "i2pd.i2pcontrol";
const char I2P_CONTROL_CERTIFICATE_ORGANIZATION[] = "Purple I2P";
class I2PControlService: public I2PControlHandlers
class I2PControlService
{
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
@@ -64,24 +63,61 @@ namespace client
private:
void InsertParam (std::ostringstream& ss, const std::string& name, int value) const;
void InsertParam (std::ostringstream& ss, const std::string& name, double value) const;
void InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value, bool quotes = true) const;
void InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const;
// methods
typedef void (I2PControlService::*MethodHandler)(const boost::property_tree::ptree& params, std::ostringstream& results);
void AuthenticateHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
void EchoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
void I2PControlHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
void RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
void RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
void NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
void ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
// I2PControl
typedef void (I2PControlService::*I2PControlRequestHandler)(const std::string& value);
void PasswordHandler (const std::string& value);
// RouterInfo
typedef void (I2PControlService::*RouterInfoRequestHandler)(std::ostringstream& results);
void UptimeHandler (std::ostringstream& results);
void VersionHandler (std::ostringstream& results);
void StatusHandler (std::ostringstream& results);
void NetDbKnownPeersHandler (std::ostringstream& results);
void NetDbActivePeersHandler (std::ostringstream& results);
void NetStatusHandler (std::ostringstream& results);
void TunnelsParticipatingHandler (std::ostringstream& results);
void TunnelsSuccessRateHandler (std::ostringstream& results);
void InboundBandwidth1S (std::ostringstream& results);
void OutboundBandwidth1S (std::ostringstream& results);
void NetTotalReceivedBytes (std::ostringstream& results);
void NetTotalSentBytes (std::ostringstream& results);
// RouterManager
typedef void (I2PControlService::*RouterManagerRequestHandler)(std::ostringstream& results);
void ShutdownHandler (std::ostringstream& results);
void ShutdownGracefulHandler (std::ostringstream& results);
void ReseedHandler (std::ostringstream& results);
// NetworkSetting
typedef void (I2PControlService::*NetworkSettingRequestHandler)(const std::string& value, std::ostringstream& results);
void InboundBandwidthLimit (const std::string& value, std::ostringstream& results);
void OutboundBandwidthLimit (const std::string& value, std::ostringstream& results);
// ClientServicesInfo
typedef void (I2PControlService::*ClientServicesInfoRequestHandler)(std::ostringstream& results);
void I2PTunnelInfoHandler (std::ostringstream& results);
void HTTPProxyInfoHandler (std::ostringstream& results);
void SOCKSInfoHandler (std::ostringstream& results);
void SAMInfoHandler (std::ostringstream& results);
void BOBInfoHandler (std::ostringstream& results);
void I2CPInfoHandler (std::ostringstream& results);
private:
std::string m_Password;
@@ -96,7 +132,10 @@ namespace client
std::map<std::string, MethodHandler> m_MethodHandlers;
std::map<std::string, I2PControlRequestHandler> m_I2PControlHandlers;
std::map<std::string, RouterInfoRequestHandler> m_RouterInfoHandlers;
std::map<std::string, RouterManagerRequestHandler> m_RouterManagerHandlers;
std::map<std::string, NetworkSettingRequestHandler> m_NetworkSettingHandlers;
std::map<std::string, ClientServicesInfoRequestHandler> m_ClientServicesInfoHandlers;
};
}
}

View File

@@ -1,390 +0,0 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <iomanip>
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/json_parser.hpp>
#include "Log.h"
#include "RouterContext.h"
#include "NetDb.hpp"
#include "Tunnel.h"
#include "Transports.h"
#include "version.h"
#include "ClientContext.h"
#include "I2PControlHandlers.h"
namespace i2p
{
namespace client
{
I2PControlHandlers::I2PControlHandlers ()
{
// RouterInfo
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlHandlers::UptimeHandler;
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlHandlers::VersionHandler;
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlHandlers::StatusHandler;
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlHandlers::NetDbKnownPeersHandler;
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlHandlers::NetDbActivePeersHandler;
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlHandlers::InboundBandwidth1S;
m_RouterInfoHandlers["i2p.router.net.bw.inbound.15s"] = &I2PControlHandlers::InboundBandwidth15S;
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlHandlers::OutboundBandwidth1S;
m_RouterInfoHandlers["i2p.router.net.bw.outbound.15s"] = &I2PControlHandlers::OutboundBandwidth15S;
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlHandlers::NetStatusHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlHandlers::TunnelsParticipatingHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlHandlers::TunnelsSuccessRateHandler;
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlHandlers::NetTotalReceivedBytes;
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlHandlers::NetTotalSentBytes;
// NetworkSetting
m_NetworkSettingHandlers["i2p.router.net.bw.in"] = &I2PControlHandlers::InboundBandwidthLimit;
m_NetworkSettingHandlers["i2p.router.net.bw.out"] = &I2PControlHandlers::OutboundBandwidthLimit;
// ClientServicesInfo
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlHandlers::I2PTunnelInfoHandler;
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlHandlers::HTTPProxyInfoHandler;
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlHandlers::SOCKSInfoHandler;
m_ClientServicesInfoHandlers["SAM"] = &I2PControlHandlers::SAMInfoHandler;
m_ClientServicesInfoHandlers["BOB"] = &I2PControlHandlers::BOBInfoHandler;
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlHandlers::I2CPInfoHandler;
}
void I2PControlHandlers::InsertParam (std::ostringstream& ss, const std::string& name, int value) const
{
ss << "\"" << name << "\":" << value;
}
void I2PControlHandlers::InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value, bool quotes) const
{
ss << "\"" << name << "\":";
if (value.length () > 0)
{
if (quotes)
ss << "\"" << value << "\"";
else
ss << value;
}
else
ss << "null";
}
void I2PControlHandlers::InsertParam (std::ostringstream& ss, const std::string& name, double value) const
{
ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value;
}
void I2PControlHandlers::InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const
{
std::ostringstream buf;
boost::property_tree::write_json (buf, value, false);
ss << "\"" << name << "\":" << buf.str();
}
// RouterInfo
void I2PControlHandlers::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
bool first = true;
for (auto it = params.begin (); it != params.end (); it++)
{
LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first);
auto it1 = m_RouterInfoHandlers.find (it->first);
if (it1 != m_RouterInfoHandlers.end ())
{
if (!first) results << ",";
else first = false;
(this->*(it1->second))(results);
}
else
LogPrint (eLogError, "I2PControl: RouterInfo unknown request ", it->first);
}
}
void I2PControlHandlers::UptimeHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.uptime", std::to_string (i2p::context.GetUptime ()*1000LL), false);
}
void I2PControlHandlers::VersionHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.version", VERSION);
}
void I2PControlHandlers::StatusHandler (std::ostringstream& results)
{
auto dest = i2p::client::context.GetSharedLocalDestination ();
InsertParam (results, "i2p.router.status", (dest && dest->IsReady ()) ? "1" : "0");
}
void I2PControlHandlers::NetDbKnownPeersHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.netdb.knownpeers", i2p::data::netdb.GetNumRouters ());
}
void I2PControlHandlers::NetDbActivePeersHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.netdb.activepeers", (int)i2p::transport::transports.GetPeers ().size ());
}
void I2PControlHandlers::NetStatusHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.net.status", (int)i2p::context.GetStatus ());
}
void I2PControlHandlers::TunnelsParticipatingHandler (std::ostringstream& results)
{
int transit = i2p::tunnel::tunnels.GetTransitTunnels ().size ();
InsertParam (results, "i2p.router.net.tunnels.participating", transit);
}
void I2PControlHandlers::TunnelsSuccessRateHandler (std::ostringstream& results)
{
int rate = i2p::tunnel::tunnels.GetTunnelCreationSuccessRate ();
InsertParam (results, "i2p.router.net.tunnels.successrate", rate);
}
void I2PControlHandlers::InboundBandwidth1S (std::ostringstream& results)
{
double bw = i2p::transport::transports.GetInBandwidth ();
InsertParam (results, "i2p.router.net.bw.inbound.1s", bw);
}
void I2PControlHandlers::InboundBandwidth15S (std::ostringstream& results)
{
double bw = i2p::transport::transports.GetInBandwidth15s ();
InsertParam (results, "i2p.router.net.bw.inbound.15s", bw);
}
void I2PControlHandlers::OutboundBandwidth1S (std::ostringstream& results)
{
double bw = i2p::transport::transports.GetOutBandwidth ();
InsertParam (results, "i2p.router.net.bw.outbound.1s", bw);
}
void I2PControlHandlers::OutboundBandwidth15S (std::ostringstream& results)
{
double bw = i2p::transport::transports.GetOutBandwidth15s ();
InsertParam (results, "i2p.router.net.bw.outbound.15s", bw);
}
void I2PControlHandlers::NetTotalReceivedBytes (std::ostringstream& results)
{
InsertParam (results, "i2p.router.net.total.received.bytes", (double)i2p::transport::transports.GetTotalReceivedBytes ());
}
void I2PControlHandlers::NetTotalSentBytes (std::ostringstream& results)
{
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
}
// network setting
void I2PControlHandlers::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
for (auto it = params.begin (); it != params.end (); it++)
{
LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first);
auto it1 = m_NetworkSettingHandlers.find (it->first);
if (it1 != m_NetworkSettingHandlers.end ()) {
if (it != params.begin ()) results << ",";
(this->*(it1->second))(it->second.data (), results);
} else
LogPrint (eLogError, "I2PControl: NetworkSetting unknown request: ", it->first);
}
}
void I2PControlHandlers::InboundBandwidthLimit (const std::string& value, std::ostringstream& results)
{
if (value != "null")
i2p::context.SetBandwidth (std::atoi(value.c_str()));
int bw = i2p::context.GetBandwidthLimit();
InsertParam (results, "i2p.router.net.bw.in", bw);
}
void I2PControlHandlers::OutboundBandwidthLimit (const std::string& value, std::ostringstream& results)
{
if (value != "null")
i2p::context.SetBandwidth (std::atoi(value.c_str()));
int bw = i2p::context.GetBandwidthLimit();
InsertParam (results, "i2p.router.net.bw.out", bw);
}
// ClientServicesInfo
void I2PControlHandlers::ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
for (auto it = params.begin (); it != params.end (); it++)
{
LogPrint (eLogDebug, "I2PControl: ClientServicesInfo request: ", it->first);
auto it1 = m_ClientServicesInfoHandlers.find (it->first);
if (it1 != m_ClientServicesInfoHandlers.end ())
{
if (it != params.begin ()) results << ",";
(this->*(it1->second))(results);
}
else
LogPrint (eLogError, "I2PControl: ClientServicesInfo unknown request ", it->first);
}
}
void I2PControlHandlers::I2PTunnelInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
boost::property_tree::ptree client_tunnels, server_tunnels;
for (auto& it: i2p::client::context.GetClientTunnels ())
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
boost::property_tree::ptree ct;
ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
client_tunnels.add_child(it.second->GetName (), ct);
}
auto& serverTunnels = i2p::client::context.GetServerTunnels ();
if (!serverTunnels.empty ()) {
for (auto& it: serverTunnels)
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
boost::property_tree::ptree st;
st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
st.put("port", it.second->GetLocalPort ());
server_tunnels.add_child(it.second->GetName (), st);
}
}
auto& clientForwards = i2p::client::context.GetClientForwards ();
if (!clientForwards.empty ())
{
for (auto& it: clientForwards)
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
boost::property_tree::ptree ct;
ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
client_tunnels.add_child(it.second->GetName (), ct);
}
}
auto& serverForwards = i2p::client::context.GetServerForwards ();
if (!serverForwards.empty ())
{
for (auto& it: serverForwards)
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
boost::property_tree::ptree st;
st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
server_tunnels.add_child(it.second->GetName (), st);
}
}
pt.add_child("client", client_tunnels);
pt.add_child("server", server_tunnels);
InsertParam (results, "I2PTunnel", pt);
}
void I2PControlHandlers::HTTPProxyInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto httpProxy = i2p::client::context.GetHttpProxy ();
if (httpProxy)
{
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
pt.put("enabled", true);
pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
}
else
pt.put("enabled", false);
InsertParam (results, "HTTPProxy", pt);
}
void I2PControlHandlers::SOCKSInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto socksProxy = i2p::client::context.GetSocksProxy ();
if (socksProxy)
{
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
pt.put("enabled", true);
pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
}
else
pt.put("enabled", false);
InsertParam (results, "SOCKS", pt);
}
void I2PControlHandlers::SAMInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto sam = i2p::client::context.GetSAMBridge ();
if (sam)
{
pt.put("enabled", true);
boost::property_tree::ptree sam_sessions;
for (auto& it: sam->GetSessions ())
{
boost::property_tree::ptree sam_session, sam_session_sockets;
auto& name = it.second->GetLocalDestination ()->GetNickname ();
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
sam_session.put("name", name);
sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
for (const auto& socket: sam->ListSockets(it.first))
{
boost::property_tree::ptree stream;
stream.put("type", socket->GetSocketType ());
stream.put("peer", socket->GetSocket ().remote_endpoint());
sam_session_sockets.push_back(std::make_pair("", stream));
}
sam_session.add_child("sockets", sam_session_sockets);
sam_sessions.add_child(it.first, sam_session);
}
pt.add_child("sessions", sam_sessions);
}
else
pt.put("enabled", false);
InsertParam (results, "SAM", pt);
}
void I2PControlHandlers::BOBInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto bob = i2p::client::context.GetBOBCommandChannel ();
if (bob)
{
/* TODO more info */
pt.put("enabled", true);
}
else
pt.put("enabled", false);
InsertParam (results, "BOB", pt);
}
void I2PControlHandlers::I2CPInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
auto i2cp = i2p::client::context.GetI2CPServer ();
if (i2cp)
{
/* TODO more info */
pt.put("enabled", true);
}
else
pt.put("enabled", false);
InsertParam (results, "I2CP", pt);
}
}
}

View File

@@ -1,82 +0,0 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifndef I2P_CONTROL_HANDLERS_H__
#define I2P_CONTROL_HANDLERS_H__
#include <sstream>
#include <map>
#include <string>
#include <boost/property_tree/ptree.hpp>
namespace i2p
{
namespace client
{
class I2PControlHandlers
{
public:
I2PControlHandlers ();
// methods
// TODO: make protected
void RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
void NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
void ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
protected:
void InsertParam (std::ostringstream& ss, const std::string& name, int value) const;
void InsertParam (std::ostringstream& ss, const std::string& name, double value) const;
void InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value, bool quotes = true) const;
void InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const;
private:
// RouterInfo
typedef void (I2PControlHandlers::*RouterInfoRequestHandler)(std::ostringstream& results);
void UptimeHandler (std::ostringstream& results);
void VersionHandler (std::ostringstream& results);
void StatusHandler (std::ostringstream& results);
void NetDbKnownPeersHandler (std::ostringstream& results);
void NetDbActivePeersHandler (std::ostringstream& results);
void NetStatusHandler (std::ostringstream& results);
void TunnelsParticipatingHandler (std::ostringstream& results);
void TunnelsSuccessRateHandler (std::ostringstream& results);
void InboundBandwidth1S (std::ostringstream& results);
void InboundBandwidth15S (std::ostringstream& results);
void OutboundBandwidth1S (std::ostringstream& results);
void OutboundBandwidth15S (std::ostringstream& results);
void NetTotalReceivedBytes (std::ostringstream& results);
void NetTotalSentBytes (std::ostringstream& results);
// NetworkSetting
typedef void (I2PControlHandlers::*NetworkSettingRequestHandler)(const std::string& value, std::ostringstream& results);
void InboundBandwidthLimit (const std::string& value, std::ostringstream& results);
void OutboundBandwidthLimit (const std::string& value, std::ostringstream& results);
// ClientServicesInfo
typedef void (I2PControlHandlers::*ClientServicesInfoRequestHandler)(std::ostringstream& results);
void I2PTunnelInfoHandler (std::ostringstream& results);
void HTTPProxyInfoHandler (std::ostringstream& results);
void SOCKSInfoHandler (std::ostringstream& results);
void SAMInfoHandler (std::ostringstream& results);
void BOBInfoHandler (std::ostringstream& results);
void I2CPInfoHandler (std::ostringstream& results);
private:
std::map<std::string, RouterInfoRequestHandler> m_RouterInfoHandlers;
std::map<std::string, NetworkSettingRequestHandler> m_NetworkSettingHandlers;
std::map<std::string, ClientServicesInfoRequestHandler> m_ClientServicesInfoHandlers;
};
}
}
#endif

View File

@@ -159,11 +159,10 @@ namespace transport
void UPnP::PortMapping ()
{
auto a = context.GetRouterInfo().GetAddresses();
if (!a) return;
for (const auto& address : *a)
const auto& a = context.GetRouterInfo().GetAddresses();
for (const auto& address : a)
{
if (address && !address->host.is_v6 () && address->port)
if (!address->host.is_v6 () && address->port)
TryPortMapping (address);
}
m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes
@@ -211,11 +210,10 @@ namespace transport
void UPnP::CloseMapping ()
{
auto a = context.GetRouterInfo().GetAddresses();
if (!a) return;
for (const auto& address : *a)
const auto& a = context.GetRouterInfo().GetAddresses();
for (const auto& address : a)
{
if (address && !address->host.is_v6 () && address->port)
if (!address->host.is_v6 () && address->port)
CloseMapping (address);
}
}
@@ -250,10 +248,10 @@ namespace transport
{
switch (address->transportStyle)
{
case i2p::data::RouterInfo::eTransportNTCP2:
case i2p::data::RouterInfo::eTransportNTCP:
return "TCP";
break;
case i2p::data::RouterInfo::eTransportSSU2:
case i2p::data::RouterInfo::eTransportSSU:
default:
return "UDP";
}

65
debian/changelog vendored
View File

@@ -1,68 +1,3 @@
i2pd (2.49.0-1) unstable; urgency=medium
* updated to version 2.49.0/0.9.60
-- orignal <orignal@i2pmail.org> Mon, 18 Sep 2023 16:00:00 +0000
i2pd (2.48.0-1) unstable; urgency=high
* updated to version 2.48.0/0.9.59
-- orignal <orignal@i2pmail.org> Mon, 12 Jun 2023 16:00:00 +0000
i2pd (2.47.0-1) unstable; urgency=high
* updated to version 2.47.0/0.9.58
-- orignal <orignal@i2pmail.org> Sat, 11 Mar 2023 16:00:00 +0000
i2pd (2.46.1-2) unstable; urgency=critical
* re-pushed release due to new critical bug
-- r4sas <r4sas@i2pmail.org> Mon, 20 Feb 2023 23:40:00 +0000
i2pd (2.46.1-1) unstable; urgency=high
* updated to version 2.46.1/0.9.57
-- r4sas <r4sas@i2pmail.org> Mon, 20 Feb 2023 02:45:00 +0000
i2pd (2.46.0-1) unstable; urgency=high
* updated to version 2.46.0/0.9.57
-- orignal <orignal@i2pmail.org> Wed, 15 Feb 2023 19:00:00 +0000
i2pd (2.45.1-1) unstable; urgency=medium
* updated to version 2.45.1/0.9.57
-- orignal <orignal@i2pmail.org> Wed, 11 Jan 2023 19:00:00 +0000
i2pd (2.45.0-1) unstable; urgency=high
* updated to version 2.45.0/0.9.57
* compat level 12
* standards version 4.3.0
* increased nofile limit in service and init.d to 8192
* added conffiles
* removed #1210 patch
-- r4sas <r4sas@i2pmail.org> Tue, 3 Jan 2023 18:00:00 +0000
i2pd (2.44.0-1) unstable; urgency=medium
* updated to version 2.44.0/0.9.56
-- orignal <orignal@i2pmail.org> Sun, 20 Nov 2022 19:00:00 +0000
i2pd (2.43.0-1) unstable; urgency=medium
* updated to version 2.43.0/0.9.55
-- orignal <orignal@i2pmail.org> Mon, 22 Aug 2022 16:00:00 +0000
i2pd (2.42.1-1) unstable; urgency=medium
* updated to version 2.42.1/0.9.54

2
debian/compat vendored
View File

@@ -1 +1 @@
12
9

4
debian/control vendored
View File

@@ -2,8 +2,8 @@ Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 12~), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 4.3.0
Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 3.9.8
Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd

6
debian/copyright vendored
View File

@@ -3,18 +3,18 @@ Upstream-Name: i2pd
Source: https://github.com/PurpleI2P
Files: *
Copyright: 2013-2023 PurpleI2P
Copyright: 2013-2020 PurpleI2P
License: BSD-3-clause
Files: debian/*
Copyright: 2013-2015 Kill Your TV <killyourtv@i2pmail.org>
2014-2016 hagen <hagen@i2pmail.org>
2016-2023 R4SAS <r4sas@i2pmail.org>
2016-2020 R4SAS <r4sas@i2pmail.org>
2017-2020 Yangfl <mmyangfl@gmail.com>
License: GPL-2+
License: BSD-3-clause
Copyright (c) 2013-2023, The PurpleI2P Project
Copyright (c) 2013-2017, The PurpleI2P Project
.
All rights reserved.
.

2
debian/i2pd.default vendored
View File

@@ -8,4 +8,4 @@ I2PD_ENABLED="yes"
DAEMON_OPTS=""
# If you have problems with hunging i2pd, you can try enable this
ulimit -n 8192
ulimit -n 4096

1
debian/i2pd.install vendored
View File

@@ -1,6 +1,7 @@
i2pd usr/sbin/
contrib/i2pd.conf etc/i2pd/
contrib/tunnels.conf etc/i2pd/
contrib/subscriptions.txt etc/i2pd/
contrib/certificates/ usr/share/i2pd/
contrib/tunnels.d/README etc/i2pd/tunnels.conf.d/
contrib/apparmor/usr.sbin.i2pd etc/apparmor.d

3
debian/i2pd.links vendored
View File

@@ -1,4 +1,5 @@
etc/i2pd/i2pd.conf var/lib/i2pd/i2pd.conf
etc/i2pd/i2pd.conf var/lib/i2pd/i2pd.conf
etc/i2pd/tunnels.conf var/lib/i2pd/tunnels.conf
etc/i2pd/subscriptions.txt var/lib/i2pd/subscriptions.txt
etc/i2pd/tunnels.conf.d var/lib/i2pd/tunnels.d
usr/share/i2pd/certificates var/lib/i2pd/certificates

27
debian/patches/01-fix-1210.patch vendored Normal file
View File

@@ -0,0 +1,27 @@
Description: fix #1210
Disables two options, which not presented in old systemd versions
Author: r4sas <r4sas@i2pmail.org>
Bug: https://github.com/PurpleI2P/i2pd/issues/1210
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2020-05-25
Index: i2pd/contrib/i2pd.service
===================================================================
--- i2pd.orig/contrib/i2pd.service
+++ i2pd/contrib/i2pd.service
@@ -6,10 +6,10 @@ After=network.target
[Service]
User=i2pd
Group=i2pd
-RuntimeDirectory=i2pd
-RuntimeDirectoryMode=0700
-LogsDirectory=i2pd
-LogsDirectoryMode=0700
+#RuntimeDirectory=i2pd
+#RuntimeDirectoryMode=0700
+#LogsDirectory=i2pd
+#LogsDirectoryMode=0700
Type=forking
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
ExecReload=/bin/sh -c "kill -HUP $MAINPID"

View File

@@ -1,17 +0,0 @@
Description: Enable UPnP usage in package
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2022-03-23
--- i2pd.orig/Makefile
+++ i2pd/Makefile
@@ -31,7 +31,7 @@ include filelist.mk
USE_AESNI := $(or $(USE_AESNI),yes)
USE_STATIC := $(or $(USE_STATIC),no)
-USE_UPNP := $(or $(USE_UPNP),no)
+USE_UPNP := $(or $(USE_UPNP),yes)
DEBUG := $(or $(DEBUG),yes)
# for debugging purposes only, when commit hash needed in trunk builds in i2pd version string

View File

@@ -1 +1,2 @@
01-upnp.patch
01-fix-1210.patch
02-upnp.patch

2
debian/rules vendored
View File

@@ -8,6 +8,6 @@ export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND =
%:
dh $@
dh $@ --parallel
override_dh_auto_install:

3
debian/watch vendored
View File

@@ -1,4 +1,3 @@
version=4
opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%i2pd-$1.tar.gz%" \
version=4 opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%i2pd-$1.tar.gz%" \
https://github.com/PurpleI2P/i2pd/tags \
(?:.*?/)?(\d[\d.]*)\.tar\.gz debian uupdate

View File

@@ -1,26 +1,7 @@
#LIB_SRC = \
# BloomFilter.cpp Gzip.cpp Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \
# Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \
# Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \
# SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
# Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \
# Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \
# Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Gost.cpp
LIB_SRC = $(wildcard $(LIB_SRC_DIR)/*.cpp)
#LIB_CLIENT_SRC = \
# AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp MatchedDestination.cpp \
# SAM.cpp SOCKS.cpp HTTPProxy.cpp I2CP.cpp
LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp)
# also: Daemon{Linux,Win32}.cpp will be added later
#DAEMON_SRC = \
# HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp
LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp)
WEBCONSOLE_SRC = $(wildcard $(WEBCONSOLE_SRC_DIR)/*.cpp)
WRAP_LIB_SRC = $(wildcard $(WRAP_SRC_DIR)/*.cpp)
DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp)
DAEMON_SRC = $(DAEMON_SRC_DIR)/Daemon.cpp $(DAEMON_SRC_DIR)/I2PControl.cpp $(DAEMON_SRC_DIR)/i2pd.cpp $(DAEMON_SRC_DIR)/UPnP.cpp

View File

@@ -64,10 +64,10 @@ namespace afrikaans // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d dag", "%d dae"}},
{"%d hours", {"%d uur", "%d ure"}},
{"%d minutes", {"%d minuut", "%d minute"}},
{"%d seconds", {"%d seconde", "%d sekondes"}},
{"days", {"dag", "dae"}},
{"hours", {"uur", "ure"}},
{"minutes", {"minuut", "minute"}},
{"seconds", {"seconde", "sekondes"}},
{"", {"", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2023, The PurpleI2P Project
* Copyright (c) 2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,16 +31,15 @@ namespace armenian // language namespace
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f ԿիԲ"},
{"%.2f MiB", "%.2f ՄիԲ"},
{"%.2f GiB", "%.2f ԳիԲ"},
{"KiB", "ԿիԲ"},
{"MiB", "ՄիԲ"},
{"GiB", "ԳիԲ"},
{"building", "կառուցվում է"},
{"failed", "Անհաջող"},
{"expiring", "Լրանում է"},
{"established", "կարգավոյված է"},
{"unknown", "անհայտ"},
{"exploratory", "հետազոտոկան"},
{"Purple I2P Webconsole", "Վեբ-կոնսոլ Purple I2P"},
{"<b>i2pd</b> webconsole", "Վեբ-կոնսոլ <b>i2pd</b>"},
{"Main page", "Գլխավոր էջ"},
{"Router commands", "Երթուղիչի հրահանգներ"},
@@ -58,10 +57,10 @@ namespace armenian // language namespace
{"Unknown", "Անհայտ"},
{"Proxy", "Պրոկսի"},
{"Mesh", "MESH-ցանց"},
{"Error", "Սխալ"},
{"Clock skew", "Ոչ ճշգրիտ ժամանակ"},
{"Offline", "Օֆլայն"},
{"Symmetric NAT", "Սիմետրիկ NAT"},
{"Full cone NAT", "Full cone NAT"},
{"Uptime", "Առկայություն"},
{"Network status", "Ցանցի կարգավիճակ"},
{"Network status v6", "Ցանցի կարգավիճակ v6"},
@@ -69,7 +68,7 @@ namespace armenian // language namespace
{"Family", "Խմբատեսակ"},
{"Tunnel creation success rate", "Հաջողությամբ կառուցված թունելներ"},
{"Received", "Ստացվել է"},
{"%.2f KiB/s", "%.2f ԿիԲ/վ"},
{"KiB/s", "ԿիԲ/վ"},
{"Sent", "Ուղարկվել է"},
{"Transit", "Տարանցում"},
{"Data path", "Տվյալների ուղին"},
@@ -90,12 +89,12 @@ namespace armenian // language namespace
{"Address registration line", "Հասցեի գրանցման տող"},
{"Domain", "Տիրույթ"},
{"Generate", "Գեներացնել"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Նշում. </b> արդյունքի տողը կարող է օգտագործվել միայն 2LD տիրույթներ գրանցելու համար (example.i2p): Ենթատիրույթներ գրանցելու համար խնդրում ենք օգտագործել i2pd-tools գործիքակազմը:"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Նշում. </b> արդյունքի տողը կարող է օգտագործվել միայն 2LD տիրույթներ գրանցելու համար (example.i2p): Ենթատիրույթներ գրանցելու համար խնդրում ենք օգտագործել i2pd-tools գործիքակազմը"},
{"Address", "Հասցե"},
{"Type", "Տեսակը"},
{"EncType", "Գաղտնագրի տեսակը"},
{"Inbound tunnels", "Մուտքային թունելներ"},
{"%dms", "%dմլվ"},
{"ms", "մլվ"},
{"Outbound tunnels", "Ելքային թունելներ"},
{"Tags", "Թեգեր"},
{"Incoming", "Մուտքային"},
@@ -113,10 +112,11 @@ namespace armenian // language namespace
{"Invalid", "Անվավեր"},
{"Store type", "Պահեստավորման տեսակը"},
{"Expires", "Սպառվում է"},
{"Non Expired Leases", "Չսպառված Lease-եր"},
{"Non Expired Leases", "Չսպառված Lease-եր"},
{"Gateway", "Դարպաս"},
{"TunnelID", "Թունելի ID"},
{"EndDate", "Ավարտ"},
{"not floodfill", "ոչ floodfill-ներ"},
{"Queue size", "Հերթի չափսը"},
{"Run peer test", "Գործարկել փորձարկումը"},
{"Decline transit tunnels", "Մերժել տարանցիկ թունելներ"},
@@ -146,7 +146,10 @@ namespace armenian // language namespace
{"Destination not found", "Հասցեի վայրը չի գտնվել"},
{"StreamID can't be null", "StreamID-ն չի կարող լինել դատարկ"},
{"Return to destination page", "Վերադառնալ նախորդ էջի հասցե"},
{"You will be redirected in 5 seconds", "Դուք կտեղափոխվեք 5 վայրկյանից"},
{"Transit tunnels count must not exceed 65535", "Տարանցիկ թունելների քանակը չպետք է գերազանցի 65535-ը"},
{"Back to commands list", "Վերադառնալ հրահանգների ցուցակ"},
{"Register at reg.i2p", "Գրանցել reg.i2p-ում"},
{"Description", "Նկարագրություն"},
{"A bit information about service on domain", "Մի փոքր տեղեկատվություն տիրոիյթում գտնվող ծառայության մասին"},
{"Submit", "Ուղարկվել"},
@@ -162,35 +165,43 @@ namespace armenian // language namespace
{"You may try to find this host on jump services below", "Ստորև Դուք կարող եք գտնել այս հոսթը jump ծառայությունների միջոցով"},
{"Invalid request", "Սխալ հարցում"},
{"Proxy unable to parse your request", "Պրոկսին չի կարող հասկանալ Ձեր հարցումը"},
{"Invalid request URI", "Սխալ ձևավորված URI հարցում"},
{"addresshelper is not supported", "addresshelper-ը համատեղելի չէ"},
{"Host", "Հոսթ"},
{"added to router's addressbook from helper", "Ավելացված է երթուղիչի հասցեագրքում helper-ի միջոցով"},
{"Click here to proceed:", "Շարունակելու համար սեղմեք այստեղ"},
{"Continue", "Շարունակել"},
{"Addresshelper found", "addresshelper-ը գնտված է"},
{"already in router's addressbook", "արդեն առկա է երթուղիչի հասցեագրքում"},
{"Click here to update record:", "Սեղմեկ այստեղ որպեսզի թարվացնեք գրառումը"},
{"invalid request uri", "Սխալ ձևավորված URI հարցում"},
{"Can't detect destination host from request", "Չհաջողվեց հայնտաբերեկ վայրի հասցեն նշված հարցմամբ"},
{"Outproxy failure", "Սխալ արտաքին պրոքսի"},
{"Bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Հոսթ %s Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"},
{"Unknown outproxy URL", "Արտաքին պրոքսիի անհայտ URL"},
{"Cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"},
{"Hostname is too long", "Հոսթի անունը չափազանց երկար է"},
{"Cannot connect to upstream SOCKS proxy", "Չհաջողվեց միանալ վերադաս SOCKS պրոկսի սերվերին"},
{"Cannot negotiate with SOCKS proxy", "Չհաջողվեց պայմանավորվել վերադաս SOCKS պրոկսիի հետ"},
{"bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"},
{"not inside I2P network, but outproxy is not enabled", "Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"},
{"unknown outproxy url", "արտաքին պրոքսիի անհայտ URL"},
{"cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"},
{"hostname too long", "Հոսթի անունը չափազանց երկար է"},
{"cannot connect to upstream socks proxy", "չհաջողվեց միանալ վերադաս socks պրոկսիին"},
{"Cannot negotiate with socks proxy", "Չհաջողվեց պայմանավորվել վերադաս socks պրոկսիի հետ"},
{"CONNECT error", "Սխալ CONNECT հարցում"},
{"Failed to connect", "Միանալ չhաջողվեց"},
{"SOCKS proxy error", "Սխալ SOCKS պրոկսի"},
{"Failed to send request to upstream", "Չհաջողվեց հարցումն ուղարկել վերադաս պրոկսիին"},
{"No reply from SOCKS proxy", "Բացակայում է պատասխանը SOCKS պրոկսի սերվերի կողմից"},
{"Cannot connect", "Հնարավոր չե միանալ"},
{"HTTP out proxy not implemented", "Արտաքին HTTP պրոկսին դեռ իրականացված չէ"},
{"Cannot connect to upstream HTTP proxy", "Չհաջողվեց միանալ վերադաս HTTP պրոկսի սերվերին"},
{"Failed to Connect", "Միանալ չhաջողվեց"},
{"socks proxy error", "Սխալ SOCKS պրոկսի"},
{"failed to send request to upstream", "Չհաջողվեց հարցումն ուղարկել վերադաս պրոկսիին"},
{"No Reply From socks proxy", "Բացակայում է պատասխանը SOCKS պրոկսի սերվերի կողմից"},
{"cannot connect", "Հնարավոր չե միանալ"},
{"http out proxy not implemented", "Արտաքին http պրոկսին դեռ իրականացված չէ"},
{"cannot connect to upstream http proxy", "Չհաջողվեց միանալ վերադաս http պրոկսի սերվերին"},
{"Host is down", "Հոսթն անհասանելի է"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ:"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ"},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d օր", "%d օր"}},
{"%d hours", {"%d ժամ", "%d ժամ"}},
{"%d minutes", {"%d րոպե", "%d րոպե"}},
{"%d seconds", {"%d վարկյան", "%d վարկյան"}},
{"days", {"օր", "օր"}},
{"hours", {"ժամ", "ժամ"}},
{"minutes", {"րոպե", "րոպե"}},
{"seconds", {"վարկյան", "վարկյան"}},
{"", {"", ""}},
};

View File

@@ -1,219 +0,0 @@
/*
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Simplified Chinese localization file
namespace i2p
{
namespace i18n
{
namespace chinese // language namespace
{
// language name in lowercase
static std::string language = "chinese";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return 0;
}
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "正在构建"},
{"failed", "连接失败"},
{"expiring", "即将过期"},
{"established", "连接成功"},
{"unknown", "未知"},
{"exploratory", "探索"},
{"Purple I2P Webconsole", "Purple I2P 网页控制台"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> 网页控制台"},
{"Main page", "主页"},
{"Router commands", "路由命令"},
{"Local Destinations", "本地目标"},
{"LeaseSets", "租约集"},
{"Tunnels", "隧道"},
{"Transit Tunnels", "中转隧道"},
{"Transports", "传输"},
{"I2P tunnels", "I2P 隧道"},
{"SAM sessions", "SAM 会话"},
{"ERROR", "错误"},
{"OK", "良好"},
{"Testing", "测试中"},
{"Firewalled", "受到防火墙限制"},
{"Unknown", "未知"},
{"Proxy", "代理"},
{"Mesh", "自组网"},
{"Clock skew", "时钟偏移"},
{"Offline", "离线"},
{"Symmetric NAT", "对称 NAT"},
{"Full cone NAT", "全锥型NAT"},
{"No Descriptors", "无描述符"},
{"Uptime", "运行时间"},
{"Network status", "IPv4 网络状态"},
{"Network status v6", "IPv6 网络状态"},
{"Stopping in", "距停止还有:"},
{"Family", "家族"},
{"Tunnel creation success rate", "隧道创建成功率"},
{"Received", "已接收"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "已发送"},
{"Transit", "中转"},
{"Data path", "数据文件路径"},
{"Hidden content. Press on text to see.", "隐藏内容 请点击此处查看。"},
{"Router Ident", "路由身份"},
{"Router Family", "路由器家族"},
{"Router Caps", "路由器类型"},
{"Version", "版本"},
{"Our external address", "外部地址"},
{"supported", "支持"},
{"Routers", "路由节点"},
{"Floodfills", "洪泛节点"},
{"Client Tunnels", "客户端隧道"},
{"Services", "服务"},
{"Enabled", "启用"},
{"Disabled", "禁用"},
{"Encrypted B33 address", "加密的 B33 地址"},
{"Address registration line", "地址域名注册"},
{"Domain", "域名"},
{"Generate", "生成"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>注意:</b> 结果字符串只能用于注册二级域名(例如example.i2p)。若需注册三级域名,请使用 i2pd-tools。"},
{"Address", "地址"},
{"Type", "类型"},
{"EncType", "加密类型"},
{"Inbound tunnels", "入站隧道"},
{"%dms", "%dms"},
{"Outbound tunnels", "出站隧道"},
{"Tags", "标签"},
{"Incoming", "传入"},
{"Outgoing", "传出"},
{"Destination", "目标"},
{"Amount", "数量"},
{"Incoming Tags", "传入标签"},
{"Tags sessions", "标签会话"},
{"Status", "状态"},
{"Local Destination", "本地目标"},
{"Streams", ""},
{"Close stream", "断开流"},
{"Such destination is not found", "找不到此目标"},
{"I2CP session not found", "未找到 I2CP 会话"},
{"I2CP is not enabled", "I2CP 未启用"},
{"Invalid", "无效"},
{"Store type", "存储类型"},
{"Expires", "过期时间"},
{"Non Expired Leases", "未到期的租约"},
{"Gateway", "网关"},
{"TunnelID", "隧道 ID"},
{"EndDate", "结束日期"},
{"floodfill mode is disabled", "洪泛已禁用"},
{"Queue size", "队列大小"},
{"Run peer test", "运行节点测试"},
{"Reload tunnels configuration", "重新载入隧道配置"},
{"Decline transit tunnels", "拒绝中转隧道"},
{"Accept transit tunnels", "允许中转隧道"},
{"Cancel graceful shutdown", "取消平滑关闭"},
{"Start graceful shutdown", "平滑关闭"},
{"Force shutdown", "强制停止"},
{"Reload external CSS styles", "重载外部 CSS 样式"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>注意:</b> 此处完成的任何操作都不是永久的,不会更改您的配置文件。"},
{"Logging level", "日志级别"},
{"Transit tunnels limit", "中转隧道限制"},
{"Change", "修改"},
{"Change language", "更改语言"},
{"no transit tunnels currently built", "目前未构建中转隧道"},
{"SAM disabled", "SAM 已禁用"},
{"no sessions currently running", "没有正在运行的会话"},
{"SAM session not found", "未找到 SAM 会话"},
{"SAM Session", "SAM 会话"},
{"Server Tunnels", "服务器隧道"},
{"Client Forwards", "客户端转发"},
{"Server Forwards", "服务器转发"},
{"Unknown page", "未知页面"},
{"Invalid token", "无效令牌"},
{"SUCCESS", "成功"},
{"Stream closed", "流已关闭"},
{"Stream not found or already was closed", "流未找到或已关闭"},
{"Destination not found", "找不到目标"},
{"StreamID can't be null", "StreamID 不能为空"},
{"Return to destination page", "返回目标页面"},
{"You will be redirected in %d seconds", "您将在%d秒内被重定向"},
{"Transit tunnels count must not exceed %d", "中转隧道数量限制为 %d"},
{"Back to commands list", "返回命令列表"},
{"Register at reg.i2p", "在 reg.i2p 注册域名"},
{"Description", "描述"},
{"A bit information about service on domain", "在此域名上运行的服务的一些信息"},
{"Submit", "提交"},
{"Domain can't end with .b32.i2p", "域名不能以 .b32.i2p 结尾"},
{"Domain must end with .i2p", "域名必须以 .i2p 结尾"},
{"Unknown command", "未知指令"},
{"Command accepted", "已接受指令"},
{"Proxy error", "代理错误"},
{"Proxy info", "代理信息"},
{"Proxy error: Host not found", "代理错误:未找到主机"},
{"Remote host not found in router's addressbook", "在路由地址簿中未找到远程主机"},
{"You may try to find this host on jump services below", "您可以尝试在下方的跳转服务中找到此主机"},
{"Invalid request", "无效请求"},
{"Proxy unable to parse your request", "代理无法解析您的请求"},
{"Addresshelper is not supported", "不支持地址助手"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "主机 %s <font color=red>已在路由地址簿中</font>。<b>请注意:此地址的来源可能是有害的!</b>点击此处更新记录:<a href=\"%s%s%s&update=true\">继续</a>"},
{"Addresshelper forced update rejected", "地址助手强制更新被拒绝"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "若要在路由器地址簿中添加主机 <b>%s</b> 请点击这里: <a href=\"%s%s%s\">继续</a>"},
{"Addresshelper request", "请求地址助手"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "主机 %s 已通过地址助手添加到路由地址簿中。点击此处继续:<a href=\"%s\">继续</a>"},
{"Addresshelper adding", "正在添加地址助手"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "主机 %s <font color=red>已在路由地址簿中</font>。点击此处更新记录:<a href=\"%s%s%s&update=true\">继续</a>"},
{"Addresshelper update", "更新地址助手"},
{"Invalid request URI", "无效的 URI 请求"},
{"Can't detect destination host from request", "无法从请求中检测到目标主机"},
{"Outproxy failure", "出口代理故障"},
{"Bad outproxy settings", "错误的出口代理设置"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "主机 %s 不在 I2P 网络内,但出口代理未启用"},
{"Unknown outproxy URL", "未知的出口代理地址"},
{"Cannot resolve upstream proxy", "无法解析上游代理"},
{"Hostname is too long", "主机名过长"},
{"Cannot connect to upstream SOCKS proxy", "无法连接到上游 SOCKS 代理"},
{"Cannot negotiate with SOCKS proxy", "无法与 SOCKS 代理协商"},
{"CONNECT error", "连接错误"},
{"Failed to connect", "连接失败"},
{"SOCKS proxy error", "SOCKS 代理错误"},
{"Failed to send request to upstream", "向上游发送请求失败"},
{"No reply from SOCKS proxy", "没有来自 SOCKS 代理的回复"},
{"Cannot connect", "无法连接"},
{"HTTP out proxy not implemented", "HTTP 出口代理未实现"},
{"Cannot connect to upstream HTTP proxy", "无法连接到上游 HTTP 代理"},
{"Host is down", "主机已关闭"},
{"Can't create connection to requested host, it may be down. Please try again later.", "无法创建到目标主机的连接。主机可能已下线,请稍后再试。"},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d 天"}},
{"%d hours", {"%d 小时"}},
{"%d minutes", {"%d 分钟"}},
{"%d seconds", {"%d 秒"}},
{"", {""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

@@ -1,204 +0,0 @@
/*
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Czech localization file
namespace i2p
{
namespace i18n
{
namespace czech // language namespace
{
// language name in lowercase
static std::string language = "czech";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return (n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2;
}
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "vytváří se"},
{"failed", "selhalo"},
{"expiring", "končící"},
{"established", "vytvořeno"},
{"unknown", "neznámý"},
{"exploratory", "průzkumné"},
{"Purple I2P Webconsole", "Purple I2P Webkonsole"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> webkonsole"},
{"Main page", "Hlavní stránka"},
{"Router commands", "Router příkazy"},
{"Local Destinations", "Lokální destinace"},
{"LeaseSets", "LeaseSety"},
{"Tunnels", "Tunely"},
{"Transit Tunnels", "Transitní tunely"},
{"Transports", "Transporty"},
{"I2P tunnels", "I2P tunely"},
{"SAM sessions", "SAM relace"},
{"ERROR", "CHYBA"},
{"OK", "OK"},
{"Testing", "Testuji"},
{"Firewalled", "Za Firewallem"},
{"Unknown", "Neznámý"},
{"Proxy", "Proxy"},
{"Mesh", "Síť"},
{"Clock skew", "Časová nesrovnalost"},
{"Offline", "Offline"},
{"Symmetric NAT", "Symetrický NAT"},
{"Uptime", "Doba provozu"},
{"Network status", "Status sítě"},
{"Network status v6", "Status sítě v6"},
{"Stopping in", "Zastavuji za"},
{"Family", "Rodina"},
{"Tunnel creation success rate", "Úspěšnost vytváření tunelů"},
{"Received", "Přijato"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Odesláno"},
{"Transit", "Tranzit"},
{"Data path", "Cesta k data souborům"},
{"Hidden content. Press on text to see.", "Skrytý kontent. Pro zobrazení, klikni na text."},
{"Router Ident", "Routerová Identita"},
{"Router Family", "Rodina routerů"},
{"Router Caps", "Omezení Routerů"},
{"Version", "Verze"},
{"Our external address", "Naše externí adresa"},
{"supported", "podporováno"},
{"Routers", "Routery"},
{"Floodfills", "Floodfilly"},
{"Client Tunnels", "Klientské tunely"},
{"Services", "Služby"},
{"Enabled", "Zapnuto"},
{"Disabled", "Vypnuto"},
{"Encrypted B33 address", "Šifrovaná adresa B33"},
{"Address registration line", "Registrační řádek adresy"},
{"Domain", "Doména"},
{"Generate", "Vygenerovat"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Poznámka:</b> výsledný řetězec může být použit pouze pro registraci 2LD domén (example.i2p). Pro registraci subdomén použijte prosím i2pd-tools."},
{"Address", "Adresa"},
{"Type", "Typ"},
{"EncType", "EncType"},
{"Inbound tunnels", "Příchozí tunely"},
{"%dms", "%dms"},
{"Outbound tunnels", "Odchozí tunely"},
{"Tags", "Štítky"},
{"Incoming", "Příchozí"},
{"Outgoing", "Odchozí"},
{"Destination", "Destinace"},
{"Amount", "Množství"},
{"Incoming Tags", "Příchozí štítky"},
{"Tags sessions", "Relace štítků"},
{"Status", "Status"},
{"Local Destination", "Lokální Destinace"},
{"Streams", "Toky"},
{"Close stream", "Uzavřít tok"},
{"I2CP session not found", "I2CP relace nenalezena"},
{"I2CP is not enabled", "I2CP není zapnuto"},
{"Invalid", "Neplatný"},
{"Store type", "Druh uložení"},
{"Expires", "Vyprší"},
{"Non Expired Leases", "Nevypršené Leasy"},
{"Gateway", "Brána"},
{"TunnelID", "ID tunelu"},
{"EndDate", "Datum ukončení"},
{"Queue size", "Velikost fronty"},
{"Run peer test", "Spustit peer test"},
{"Decline transit tunnels", "Odmítnout tranzitní tunely"},
{"Accept transit tunnels", "Přijmout tranzitní tunely"},
{"Cancel graceful shutdown", "Zrušit hladké vypnutí"},
{"Start graceful shutdown", "Zahájit hladké vypnutí"},
{"Force shutdown", "Vynutit vypnutí"},
{"Reload external CSS styles", "Znovu načíst externí CSS"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Poznámka:</b> žádná vykonaná akce zde není trvalá a nemění konfigurační soubory."},
{"Logging level", "Úroveň logování"},
{"Transit tunnels limit", "Limit tranzitních tunelů"},
{"Change", "Změnit"},
{"Change language", "Změnit jazyk"},
{"no transit tunnels currently built", "Žádný tranzitní tunel není momentálně vytvořen"},
{"SAM disabled", "SAM vypnutý"},
{"no sessions currently running", "Momentálně nejsou spuštěné žádné relace"},
{"SAM session not found", "SAM relace nenalezena"},
{"SAM Session", "SAM Relace"},
{"Server Tunnels", "Server Tunely"},
{"Client Forwards", "Přesměrování Klienta"},
{"Server Forwards", "Přesměrování Serveru"},
{"Unknown page", "Neznámá stránka"},
{"Invalid token", "Neplatný token"},
{"SUCCESS", "ÚSPĚCH"},
{"Stream closed", "Tok uzavřen"},
{"Stream not found or already was closed", "Tok nenalezen nebo byl již uzavřen"},
{"Destination not found", "Destinace nenalezena"},
{"StreamID can't be null", "StreamID nemůže být null"},
{"Return to destination page", "Zpět na stránku destinací"},
{"Back to commands list", "Zpět na list příkazů"},
{"Register at reg.i2p", "Zaregistrovat na reg.i2p"},
{"Description", "Popis"},
{"A bit information about service on domain", "Trochu informací o službě na doméně"},
{"Submit", "Odeslat"},
{"Domain can't end with .b32.i2p", "Doména nesmí končit na .b32.i2p"},
{"Domain must end with .i2p", "Doména musí končit s .i2p"},
{"Such destination is not found", "Takováto destinace nebyla nalezena"},
{"Unknown command", "Neznámý příkaz"},
{"Command accepted", "Příkaz přijat"},
{"Proxy error", "Chyba proxy serveru"},
{"Proxy info", "Proxy informace"},
{"Proxy error: Host not found", "Chyba proxy serveru: Hostitel nenalezen"},
{"Remote host not found in router's addressbook", "Vzdálený hostitel nebyl nalezen v adresáři routeru"},
{"You may try to find this host on jump services below", "Můžete se pokusit najít tohoto hostitele na startovacích službách níže"},
{"Invalid request", "Neplatný požadavek"},
{"Proxy unable to parse your request", "Proxy server nemohl zpracovat váš požadavek"},
{"Invalid request URI", "Neplatný URI požadavek"},
{"Can't detect destination host from request", "Nelze zjistit cílového hostitele z požadavku"},
{"Outproxy failure", "Outproxy selhání"},
{"Bad outproxy settings", "Špatné outproxy nastavení"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Hostitel %s není uvnitř I2P sítě a outproxy není nastavena"},
{"Unknown outproxy URL", "Neznámá outproxy URL"},
{"Cannot resolve upstream proxy", "Nelze rozluštit upstream proxy server"},
{"Hostname is too long", "Název hostitele je příliš dlouhý"},
{"Cannot connect to upstream SOCKS proxy", "Nelze se připojit k upstream SOCKS proxy serveru"},
{"Cannot negotiate with SOCKS proxy", "Nelze vyjednávat se SOCKS proxy serverem"},
{"CONNECT error", "Chyba PŘIPOJENÍ"},
{"Failed to connect", "Připojení se nezdařilo"},
{"SOCKS proxy error", "Chyba SOCKS proxy serveru"},
{"Failed to send request to upstream", "Odeslání žádosti upstream serveru se nezdařilo"},
{"No reply from SOCKS proxy", "Žádná odpověď od SOCKS proxy serveru"},
{"Cannot connect", "Nelze se připojit"},
{"HTTP out proxy not implemented", "HTTP out proxy není implementován"},
{"Cannot connect to upstream HTTP proxy", "Nelze se připojit k upstream HTTP proxy serveru"},
{"Host is down", "Hostitel je nedostupný"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Připojení k požadovanému hostiteli nelze vytvořit, může být nedostupný. Zkuste to, prosím, znovu později."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d den", "%d dny", "%d dní", "%d dní"}},
{"%d hours", {"%d hodina", "%d hodiny", "%d hodin", "%d hodin"}},
{"%d minutes", {"%d minuta", "%d minuty", "%d minut", "%d minut"}},
{"%d seconds", {"%d vteřina", "%d vteřiny", "%d vteřin", "%d vteřin"}},
{"", {"", "", "", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, The PurpleI2P Project
* Copyright (c) 2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,185 +31,64 @@ namespace french // language namespace
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f Kio"},
{"%.2f MiB", "%.2f Mio"},
{"%.2f GiB", "%.2f Gio"},
{"KiB", "Kio"},
{"MiB", "Mio"},
{"GiB", "Gio"},
{"building", "En construction"},
{"failed", "échoué"},
{"failed", "echoué"},
{"expiring", "expiré"},
{"established", "établi"},
{"unknown", "inconnu"},
{"exploratory", "exploratoire"},
{"Purple I2P Webconsole", "Console web Purple I2P"},
{"<b>i2pd</b> webconsole", "Console web <b>i2pd</b>"},
{"Main page", "Page principale"},
{"Router commands", "Commandes du routeur"},
{"Local Destinations", "Destinations locales"},
{"LeaseSets", "Jeu de baux"},
{"Tunnels", "Tunnels"},
{"Transit Tunnels", "Tunnels transitoires"},
{"Transports", "Transports"},
{"I2P tunnels", "Tunnels I2P"},
{"SAM sessions", "Sessions SAM"},
{"ERROR", "ERREUR"},
{"OK", "OK"},
{"Testing", "Test en cours"},
{"Firewalled", "Derrière un pare-feu"},
{"Unknown", "Inconnu"},
{"Proxy", "Proxy"},
{"Mesh", "Maillé"},
{"Clock skew", "Horloge décalée"},
{"Error", "Erreur"},
{"Offline", "Hors ligne"},
{"Symmetric NAT", "NAT symétrique"},
{"Full cone NAT", "NAT à cône complet"},
{"No Descriptors", "Aucuns Descripteurs"},
{"Uptime", "Temps de fonctionnement"},
{"Network status", "État du réseau"},
{"Network status v6", "État du réseau v6"},
{"Stopping in", "Arrêt dans"},
{"Family", "Famille"},
{"Tunnel creation success rate", "Taux de succès de création de tunnels"},
{"Total tunnel creation success rate", "Taux de réussite de création de tunnel"},
{"Received", "Reçu"},
{"%.2f KiB/s", "%.2f Kio/s"},
{"KiB/s", "kio/s"},
{"Sent", "Envoyé"},
{"Transit", "Transité"},
{"Data path", "Emplacement des données"},
{"Hidden content. Press on text to see.", "Contenu caché. Cliquez sur le texte pour afficher."},
{"Transit", "Transit"},
{"Hidden content. Press on text to see.", "Contenu caché. Cliquez sur le texte pour regarder."},
{"Router Ident", "Identifiant du routeur"},
{"Router Family", "Famille du routeur"},
{"Router Caps", "Limiteurs du routeur"},
{"Version", "Version"},
{"Our external address", "Notre adresse externe"},
{"supported", "supporté"},
{"Routers", "Routeurs"},
{"Floodfills", "Remplisseurs"},
{"Client Tunnels", "Tunnels clients"},
{"Services", "Services"},
{"Enabled", "Activé"},
{"Disabled", "Désactivé"},
{"Encrypted B33 address", "Adresse B33 chiffrée"},
{"Address registration line", "Ligne d'inscription de l'adresse"},
{"Domain", "Domaine"},
{"Generate", "Générer"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Note :</b> La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Note:</b> La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."},
{"Address", "Adresse"},
{"Type", "Type"},
{"EncType", "EncType"},
{"Expire LeaseSet", "Expirer le jeu de baux"},
{"Inbound tunnels", "Tunnels entrants"},
{"%dms", "%dms"},
{"ms", "ms"},
{"Outbound tunnels", "Tunnels sortants"},
{"Tags", "Balises"},
{"Incoming", "Entrant"},
{"Outgoing", "Sortant"},
{"Destination", "Destination"},
{"Amount", "Quantité"},
{"Incoming Tags", "Balises entrantes"},
{"Tags sessions", "Sessions des balises"},
{"Status", "Statut"},
{"Local Destination", "Destination locale"},
{"Streams", "Flux"},
{"Close stream", "Fermer le flux"},
{"Such destination is not found", "Cette destination est introuvable"},
{"I2CP session not found", "Session I2CP introuvable"},
{"I2CP is not enabled", "I2CP est désactivé"},
{"Invalid", "Invalide"},
{"Store type", "Type de stockage"},
{"Expires", "Expire"},
{"Non Expired Leases", "Baux non expirés"},
{"Gateway", "Passerelle"},
{"TunnelID", "ID du tunnel"},
{"EndDate", "Date de fin"},
{"floodfill mode is disabled", "le mode de remplissage est désactivé"},
{"Queue size", "Longueur de la file"},
{"Run peer test", "Lancer test des pairs"},
{"Reload tunnels configuration", "Recharger la configuration des tunnels"},
{"Decline transit tunnels", "Refuser les tunnels transitoires"},
{"Accept transit tunnels", "Accepter les tunnels transitoires"},
{"Cancel graceful shutdown", "Annuler l'arrêt gracieux"},
{"Start graceful shutdown", "Démarrer l'arrêt gracieux"},
{"Force shutdown", "Forcer l'arrêt"},
{"Reload external CSS styles", "Rafraîchir les styles CSS externes"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Note :</b> Toute action effectuée ici n'est pas permanente et ne modifie pas vos fichiers de configuration."},
{"Logging level", "Niveau de journalisation"},
{"Transit tunnels limit", "Limite sur les tunnels transitoires"},
{"Change", "Changer"},
{"Change language", "Changer la langue"},
{"no transit tunnels currently built", "aucun tunnel transitoire présentement établi"},
{"SAM disabled", "SAM désactivé"},
{"no sessions currently running", "aucune session présentement en cours"},
{"SAM session not found", "session SAM introuvable"},
{"SAM Session", "Session SAM"},
{"Server Tunnels", "Tunnels serveurs"},
{"Client Forwards", "Transmission du client"},
{"Server Forwards", "Transmission du serveur"},
{"Unknown page", "Page inconnue"},
{"Invalid token", "Jeton invalide"},
{"SUCCESS", "SUCCÈS"},
{"Stream closed", "Flux fermé"},
{"Stream not found or already was closed", "Flux introuvable ou déjà fermé"},
{"Destination not found", "Destination introuvable"},
{"StreamID can't be null", "StreamID ne peut pas être vide"},
{"Return to destination page", "Retourner à la page de destination"},
{"You will be redirected in %d seconds", "Vous serez redirigé dans %d secondes"},
{"LeaseSet expiration time updated", "Temps d'expiration du jeu de baux mis à jour"},
{"LeaseSet is not found or already expired", "Le jeu de baux est introuvable ou a déjà expiré"},
{"Transit tunnels count must not exceed %d", "Le nombre de tunnels de transit ne doit pas excéder %d"},
{"Back to commands list", "Retour à la liste des commandes"},
{"Register at reg.i2p", "Inscription à reg.i2p"},
{"Description", "Description"},
{"A bit information about service on domain", "Un peu d'information à propos des services disponibles dans le domaine"},
{"Submit", "Soumettre"},
{"Domain can't end with .b32.i2p", "Le domaine ne peut pas terminer par .b32.i2p"},
{"Domain must end with .i2p", "Le domaine doit terminer par .i2p"},
{"Unknown command", "Commande inconnue"},
{"Command accepted", "Commande acceptée"},
{"Proxy error", "Erreur de proxy"},
{"Proxy info", "Information sur le proxy"},
{"Proxy error: Host not found", "Erreur de proxy : Hôte introuvable"},
{"Remote host not found in router's addressbook", "Hôte distant introuvable dans le carnet d'adresse du routeur"},
{"You may try to find this host on jump services below", "Vous pouvez essayer de trouver cet hôte sur des services de redirection ci-dessous"},
{"Invalid request", "Requête invalide"},
{"Proxy unable to parse your request", "Proxy incapable de comprendre votre requête"},
{"Addresshelper is not supported", "Assistant d'adresse non supporté"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'hôte %s est <font color=red>déjà dans le carnet d'adresses du routeur</font>. <b>Attention : la source de cette URL peut être nuisible !</b> Cliquez ici pour mettre à jour l'enregistrement : <a href=\"%s%s%s&update=true\">Continuer</a>."},
{"Addresshelper forced update rejected", "Mise à jour forcée des assistants d'adresses rejetée"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Pour ajouter l'hôte <b>%s</b> au carnet d'adresses du routeur, cliquez ici : <a href=\"%s%s%s\">Continuer</a>."},
{"Addresshelper request", "Demande à l'assistant d'adresse"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "L'hôte %s a été ajouté au carnet d'adresses du routeur depuis l'assistant. Cliquez ici pour continuer : <a href=\"%s\">Continuer</a>."},
{"Addresshelper adding", "Ajout de l'assistant d'adresse"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'hôte %s est <font color=red>déjà dans le carnet d'adresses du routeur</font>. Cliquez ici pour mettre à jour le dossier : <a href=\"%s%s%s&update=true\">Continuer</a>."},
{"Addresshelper update", "Mise à jour de l'assistant d'adresse"},
{"Invalid request URI", "URI de la requête invalide"},
{"Can't detect destination host from request", "Impossible de détecter l'hôte de destination à partir de la requête"},
{"Outproxy failure", "Échec de proxy de sortie"},
{"Bad outproxy settings", "Mauvaise configuration du proxy de sortie"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Hôte %s pas dans le réseau I2P, mais le proxy de sortie n'est pas activé"},
{"Unknown outproxy URL", "URL du proxy de sortie inconnu"},
{"Cannot resolve upstream proxy", "Impossible de résoudre l'adresse du proxy en amont"},
{"Hostname is too long", "Nom d'hôte trop long"},
{"Cannot connect to upstream SOCKS proxy", "Impossible de se connecter au proxy SOCKS en amont"},
{"Cannot negotiate with SOCKS proxy", "Impossible de négocier avec le proxy SOCKS"},
{"CONNECT error", "Erreur de connexion"},
{"Failed to connect", "Échec de connexion"},
{"SOCKS proxy error", "Erreur de proxy SOCKS"},
{"Failed to send request to upstream", "Erreur lors de l'envoie de la requête en amont"},
{"No reply from SOCKS proxy", "Pas de réponse du proxy SOCKS"},
{"Cannot connect", "Impossible de connecter"},
{"HTTP out proxy not implemented", "Proxy de sortie HTTP non implémenté"},
{"Cannot connect to upstream HTTP proxy", "Impossible de se connecter au proxy HTTP en amont"},
{"Host is down", "Hôte hors service"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Impossible d'établir une connexion avec l'hôte, il est peut-être hors service. Veuillez réessayer plus tard."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d jour", "%d jours"}},
{"%d hours", {"%d heure", "%d heures"}},
{"%d minutes", {"%d minute", "%d minutes"}},
{"%d seconds", {"%d seconde", "%d secondes"}},
{"days", {"jour", "jours"}},
{"hours", {"heure", "heures"}},
{"minutes", {"minute", "minutes"}},
{"seconds", {"seconde", "secondes"}},
{"", {"", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, The PurpleI2P Project
* Copyright (c) 2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,20 +31,19 @@ namespace german // language namespace
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"building", "In Bau"},
{"failed", "fehlgeschlagen"},
{"expiring", "läuft ab"},
{"expiring", "läuft ab in"},
{"established", "hergestellt"},
{"unknown", "Unbekannt"},
{"exploratory", "erforschend"},
{"Purple I2P Webconsole", "Purple I2P-Webkonsole"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b>-Webkonsole"},
{"exploratory", "erforschende"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> Webkonsole"},
{"Main page", "Startseite"},
{"Router commands", "Routerbefehle"},
{"Local Destinations", "Lokale Ziele"},
{"Router commands", "Router Befehle"},
{"Local Destinations", "Lokale Destination"},
{"LeaseSets", "LeaseSets"},
{"Tunnels", "Tunnel"},
{"Transit Tunnels", "Transittunnel"},
@@ -54,14 +53,14 @@ namespace german // language namespace
{"ERROR", "FEHLER"},
{"OK", "OK"},
{"Testing", "Testen"},
{"Firewalled", "Hinter einer Firewall"},
{"Firewalled", "Hinter eine Firewall"},
{"Unknown", "Unbekannt"},
{"Proxy", "Proxy"},
{"Mesh", "Mesh"},
{"Error", "Fehler"},
{"Clock skew", "Zeitabweichung"},
{"Offline", "Offline"},
{"Symmetric NAT", "Symmetrisches NAT"},
{"No Descriptors", "Keine Beschreibungen"},
{"Uptime", "Laufzeit"},
{"Network status", "Netzwerkstatus"},
{"Network status v6", "Netzwerkstatus v6"},
@@ -69,7 +68,7 @@ namespace german // language namespace
{"Family", "Familie"},
{"Tunnel creation success rate", "Erfolgsrate der Tunnelerstellung"},
{"Received", "Eingegangen"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"KiB/s", "KiB/s"},
{"Sent", "Gesendet"},
{"Transit", "Transit"},
{"Data path", "Datenpfad"},
@@ -82,33 +81,33 @@ namespace german // language namespace
{"supported", "unterstützt"},
{"Routers", "Router"},
{"Floodfills", "Floodfills"},
{"Client Tunnels", "Clienttunnel"},
{"Client Tunnels", "Klienttunnel"},
{"Services", "Services"},
{"Enabled", "Aktiviert"},
{"Disabled", "Deaktiviert"},
{"Encrypted B33 address", "Verschlüsselte B33-Adresse"},
{"Address registration line", "Adressregistrierungszeile"},
{"Encrypted B33 address", "Verschlüsselte B33 Adresse"},
{"Address registration line", "Adresseregistrierungszeile"},
{"Domain", "Domain"},
{"Generate", "Generieren"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Hinweis:</b> Der resultierende String kann nur für die Registrierung einer 2LD-Domain (beispiel.i2p) benutzt werden. Für die Registrierung von Subdomains kann i2pd-tools verwendet werden."},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Hinweis:</b> Der resultierende String kann nur für die Registrierung einer 2LD Domain (beispiel.i2p) benutzt werden. Für die Registrierung von Subdomains kann i2pd-tools verwendet werden."},
{"Address", "Adresse"},
{"Type", "Typ"},
{"EncType", "Verschlüsselungstyp"},
{"Inbound tunnels", "Eingehende Tunnel"},
{"%dms", "%dms"},
{"ms", "ms"},
{"Outbound tunnels", "Ausgehende Tunnel"},
{"Tags", "Tags"},
{"Incoming", "Eingehend"},
{"Outgoing", "Ausgehend"},
{"Destination", "Ziel"},
{"Destination", "Destination"},
{"Amount", "Anzahl"},
{"Incoming Tags", "Eingehende Tags"},
{"Tags sessions", "Tags-Sitzungen"},
{"Tags sessions", "Tags Sitzungen"},
{"Status", "Status"},
{"Local Destination", "Lokales Ziel"},
{"Local Destination", "Lokale Destination"},
{"Streams", "Streams"},
{"Close stream", "Stream schließen"},
{"I2CP session not found", "I2CP-Sitzung nicht gefunden"},
{"I2CP session not found", "I2CP Sitzung nicht gefunden"},
{"I2CP is not enabled", "I2CP ist nicht aktiviert"},
{"Invalid", "Ungültig"},
{"Store type", "Speichertyp"},
@@ -117,94 +116,92 @@ namespace german // language namespace
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "Enddatum"},
{"floodfill mode is disabled", "Floodfill Modus ist deaktiviert"},
{"Queue size", "Größe der Warteschlange"},
{"Run peer test", "Peer-Test durchführen"},
{"Reload tunnels configuration", "Tunnel Konfiguration neu laden"},
{"not floodfill", "kein Floodfill"},
{"Queue size", "Warteschlangengröße"},
{"Run peer test", "Peer-Test ausführen"},
{"Decline transit tunnels", "Transittunnel ablehnen"},
{"Accept transit tunnels", "Transittunnel akzeptieren"},
{"Cancel graceful shutdown", "Beende das kontrollierte Herunterfahren"},
{"Cancel graceful shutdown", "Beende das kontrollierte herunterfahren"},
{"Start graceful shutdown", "Starte das kontrollierte Herunterfahren"},
{"Force shutdown", "Herunterfahren erzwingen"},
{"Reload external CSS styles", "Lade externe CSS-Stile neu"},
{"Reload external CSS styles", "Lade externe CSS-Styles neu"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Hinweis:</b> Alle hier durchgeführten Aktionen sind nicht dauerhaft und ändern die Konfigurationsdateien nicht."},
{"Logging level", "Protokollierungslevel"},
{"Transit tunnels limit", "Limit für Transittunnel"},
{"Change", "Ändern"},
{"Change", "Verändern"},
{"Change language", "Sprache ändern"},
{"no transit tunnels currently built", "derzeit keine Transittunnel aufgebaut"},
{"SAM disabled", "SAM deaktiviert"},
{"no sessions currently running", "Derzeit keine laufenden Sitzungen"},
{"SAM session not found", "SAM-Sitzung nicht gefunden"},
{"SAM Session", "SAM-Sitzung"},
{"SAM session not found", "SAM Sitzung nicht gefunden"},
{"SAM Session", "SAM Sitzung"},
{"Server Tunnels", "Servertunnel"},
{"Client Forwards", "Client-Weiterleitungen"},
{"Client Forwards", "Klient-Weiterleitungen"},
{"Server Forwards", "Server-Weiterleitungen"},
{"Unknown page", "Unbekannte Seite"},
{"Invalid token", "Ungültiger Token"},
{"SUCCESS", "ERFOLGREICH"},
{"Stream closed", "Stream geschlossen"},
{"Stream not found or already was closed", "Stream nicht gefunden oder bereits geschlossen"},
{"Destination not found", "Ziel nicht gefunden"},
{"Destination not found", "Destination nicht gefunden"},
{"StreamID can't be null", "StreamID kann nicht null sein"},
{"Return to destination page", "Zurück zur Ziel-Seite"},
{"You will be redirected in %d seconds", "Du wirst umgeleitet in %d Sekunden"},
{"Transit tunnels count must not exceed %d", "Die Anzahl der Transittunnel darf nicht über %d gehen"},
{"Back to commands list", "Zurück zur Befehlsliste"},
{"Return to destination page", "Zurück zur Destination-Seite"},
{"You will be redirected in 5 seconds", "Du wirst in 5 Sekunden weitergeleitet"},
{"Transit tunnels count must not exceed 65535", "Es darf maximal 65535 Transittunnel geben"},
{"Back to commands list", "Zurück zur Kommandoliste"},
{"Register at reg.i2p", "Auf reg.i2p registrieren"},
{"Description", "Beschreibung"},
{"A bit information about service on domain", "Ein paar Informationen über den Service auf der Domain"},
{"Submit", "Absenden"},
{"Domain can't end with .b32.i2p", "Domain kann nicht auf .b32.i2p enden"},
{"Domain must end with .i2p", "Domain muss auf .i2p enden"},
{"Such destination is not found", "Ein solches Ziel konnte nicht gefunden werden"},
{"A bit information about service on domain", "Ein bisschen Informationen über den Service auf der Domain"},
{"Submit", "Einreichen"},
{"Domain can't end with .b32.i2p", "Domain kann nicht mit .b32.i2p enden"},
{"Domain must end with .i2p", "Domain muss mit .i2p enden"},
{"Such destination is not found", "Eine solche Destination konnte nicht gefunden werden"},
{"Unknown command", "Unbekannter Befehl"},
{"Command accepted", "Befehl akzeptiert"},
{"Proxy error", "Proxy-Fehler"},
{"Proxy info", "Proxy-Info"},
{"Proxy error: Host not found", "Proxy-Fehler: Host nicht gefunden"},
{"Remote host not found in router's addressbook", "Remote-Host nicht im Router-Adressbuch gefunden"},
{"You may try to find this host on jump services below", "Vielleicht kannst du diesen Host auf einem der nachfolgenden Jump-Services finden"},
{"Remote host not found in router's addressbook", "Remote-Host nicht im Router Adressbuch gefunden"},
{"You may try to find this host on jump services below", "Vielleicht kannst du diesen Host auf einen der Jump-Services unten finden"},
{"Invalid request", "Ungültige Anfrage"},
{"Proxy unable to parse your request", "Proxy konnte die Anfrage nicht verarbeiten"},
{"Addresshelper is not supported", "Adresshelfer wird nicht unterstützt"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Host %s ist <font color=red>bereits im Adressbuch des Routers</font>. <b>Vorsicht: Die Quelle dieser URL kann schädlich sein!</b> Klicken Sie hier, um den Datensatz zu aktualisieren: <a href=\"%s%s%s&update=true\">Weiter</a>."},
{"Addresshelper forced update rejected", "Adresshelfer gezwungene Aktualisierung abgelehnt"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Um den Host <b>%s</b> im Adressbuch des Routers hinzuzufügen, klicken Sie hier: <a href=\"%s%s%s\">Weiter</a>."},
{"Addresshelper request", "Adresshelfer gefunden"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Host %s wurde vom Helfer zum Adressbuch des Routers hinzugefügt. Klicken Sie hier, um fortzufahren: <a href=\"%s\">Weiter</a>."},
{"Addresshelper adding", "Adresshelfer hinzufügen"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Host %s ist <font color=red>bereits im Adressbuch des Routers</font>. Klicken Sie hier, um den Eintrag zu aktualisieren: <a href=\"%s%s%s&update=true\">Weiter</a>."},
{"Addresshelper update", "Adresshelfer aktualisieren"},
{"Invalid request URI", "Ungültige Anfrage-URI"},
{"Can't detect destination host from request", "Kann den Ziel-Host von der Anfrage nicht erkennen"},
{"Proxy unable to parse your request", "Proxy konnte die Anfrage nicht interpretieren"},
{"addresshelper is not supported", "addresshelper wird nicht unterstützt"},
{"Host", "Host"},
{"added to router's addressbook from helper", "vom Helfer zum Router Adressbuch hinzugefügt"},
{"Click here to proceed:", "Klicke hier um fortzufahren:"},
{"Continue", "Fortsetzen"},
{"Addresshelper found", "Adresshelfer gefunden"},
{"already in router's addressbook", "bereits im Adressbuch des Routers"},
{"Click here to update record:", "Klicke hier, um den Eintrag zu aktualisieren:"},
{"invalid request uri", "ungültige Anfrage-URI"},
{"Can't detect destination host from request", "Kann Anhand der Anfrage den Destination-Host nicht erkennen"},
{"Outproxy failure", "Outproxy-Fehler"},
{"Bad outproxy settings", "Ungültige Outproxy-Einstellungen"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Host %s außerhalb des I2P-Netzwerks, aber Outproxy ist nicht aktiviert"},
{"Unknown outproxy URL", "Unbekannte Outproxy-URL"},
{"Cannot resolve upstream proxy", "Kann den Upstream-Proxy nicht auflösen"},
{"Hostname is too long", "Hostname zu lang"},
{"Cannot connect to upstream SOCKS proxy", "Kann keine Verbindung zum Upstream-SOCKS-Proxy herstellen"},
{"Cannot negotiate with SOCKS proxy", "Kann nicht mit SOCKS-Proxy verhandeln"},
{"bad outproxy settings", "ungültige Outproxy-Einstellungen"},
{"not inside I2P network, but outproxy is not enabled", "nicht innerhalb des I2P-Netzwerks, aber Outproxy ist nicht aktiviert"},
{"unknown outproxy url", "unbekannte Outproxy-URL"},
{"cannot resolve upstream proxy", "kann den Upstream-Proxy nicht auflösen"},
{"hostname too long", "Hostname zu lang"},
{"cannot connect to upstream socks proxy", "Kann keine Verbindung zum Upstream-Socks-Proxy herstellen"},
{"Cannot negotiate with socks proxy", "Kann nicht mit Socks-Proxy verhandeln"},
{"CONNECT error", "CONNECT-Fehler"},
{"Failed to connect", "Verbindung konnte nicht hergestellt werden"},
{"SOCKS proxy error", "SOCKS-Proxy-Fehler"},
{"Failed to send request to upstream", "Anfrage an den Upstream zu senden ist gescheitert"},
{"No reply from SOCKS proxy", "Keine Antwort vom SOCKS-Proxy"},
{"Cannot connect", "Kann nicht verbinden"},
{"HTTP out proxy not implemented", "HTTP-Outproxy nicht implementiert"},
{"Cannot connect to upstream HTTP proxy", "Kann nicht zu Upstream-HTTP-Proxy verbinden"},
{"Failed to Connect", "Verbindung konnte nicht hergestellt werden"},
{"socks proxy error", "Socks-Proxy-Fehler"},
{"failed to send request to upstream", "Anfrage an den Upstream zu senden ist gescheitert"},
{"No Reply From socks proxy", "Keine Antwort vom Socks-Proxy"},
{"cannot connect", "kann nicht verbinden"},
{"http out proxy not implemented", "HTTP-Outproxy nicht implementiert"},
{"cannot connect to upstream http proxy", "Kann nicht zu Upstream-HTTP-Proxy verbinden"},
{"Host is down", "Host ist offline"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Konnte keine Verbindung zum angefragten Host aufbauen, vielleicht ist er offline. Versuche es später noch mal."},
{"Can't create connection to requested host, it may be down. Please try again later.", "Konnte keine Verbindung zum angefragten Host aufbaunen, vielleicht ist es offline. Versuche es später noch einmal."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d Tag", "%d Tage"}},
{"%d hours", {"%d Stunde", "%d Stunden"}},
{"%d minutes", {"%d Minute", "%d Minuten"}},
{"%d seconds", {"%d Sekunde", "%d Sekunden"}},
{"days", {"Tag", "Tage"}},
{"hours", {"Stunde", "Stunden"}},
{"minutes", {"Minute", "Minuten"}},
{"seconds", {"Sekunde", "Sekunden"}},
{"", {"", ""}},
};

View File

@@ -1,43 +0,0 @@
/*
* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <clocale>
#include "ClientContext.h"
#include "I18N_langs.h"
#include "I18N.h"
namespace i2p
{
namespace i18n
{
void SetLanguage(const std::string &lang)
{
const auto it = i2p::i18n::languages.find(lang);
if (it == i2p::i18n::languages.end()) // fallback
{
i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale());
setlocale(LC_NUMERIC, "english");
}
else
{
i2p::client::context.SetLanguage (it->second.LocaleFunc());
setlocale(LC_NUMERIC, lang.c_str()); // set decimal point based on language
}
}
std::string translate (const std::string& arg)
{
return i2p::client::context.GetLanguage ()->GetString (arg);
}
std::string translate (const std::string& arg, const std::string& arg2, const int& n)
{
return i2p::client::context.GetLanguage ()->GetPlural (arg, arg2, n);
}
} // i18n
} // i2p

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2023, The PurpleI2P Project
* Copyright (c) 2021-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -9,127 +9,37 @@
#ifndef __I18N_H__
#define __I18N_H__
#include <string>
#include <map>
#include <utility>
#include <functional>
#include "ClientContext.h"
namespace i2p
{
namespace i18n
{
class Locale
inline void SetLanguage(const std::string &lang)
{
public:
Locale (
const std::string& language,
const std::map<std::string, std::string>& strings,
const std::map<std::string, std::vector<std::string>>& plurals,
std::function<int(int)> formula
): m_Language (language), m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { };
const auto it = i2p::i18n::languages.find(lang);
if (it == i2p::i18n::languages.end()) // fallback
i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale());
else
i2p::client::context.SetLanguage (it->second.LocaleFunc());
}
// Get activated language name for webconsole
std::string GetLanguage() const
{
return m_Language;
}
inline std::string translate (const std::string& arg)
{
return i2p::client::context.GetLanguage ()->GetString (arg);
}
std::string GetString (const std::string& arg) const
{
const auto it = m_Strings.find(arg);
if (it == m_Strings.end())
{
return arg;
}
else
{
return it->second;
}
}
std::string GetPlural (const std::string& arg, const std::string& arg2, const int& n) const
{
const auto it = m_Plurals.find(arg2);
if (it == m_Plurals.end()) // not found, fallback to english
{
return n == 1 ? arg : arg2;
}
else
{
int form = m_Formula(n);
return it->second[form];
}
}
private:
const std::string m_Language;
const std::map<std::string, std::string> m_Strings;
const std::map<std::string, std::vector<std::string>> m_Plurals;
std::function<int(int)> m_Formula;
};
void SetLanguage(const std::string &lang);
std::string translate (const std::string& arg);
std::string translate (const std::string& arg, const std::string& arg2, const int& n);
inline std::string translate (const std::string& arg, const std::string& arg2, const int& n)
{
return i2p::client::context.GetLanguage ()->GetPlural (arg, arg2, n);
}
} // i18n
} // i2p
/**
* @brief Get translation of string
* @param arg String with message
*/
template<typename TValue>
std::string tr (TValue&& arg)
template<typename... TArgs>
std::string tr (TArgs&&... args)
{
return i2p::i18n::translate(std::forward<TValue>(arg));
}
/**
* @brief Get translation of string and format it
* @param arg String with message
* @param args Array of arguments for string formatting
*/
template<typename TValue, typename... TArgs>
std::string tr (TValue&& arg, TArgs&&... args)
{
std::string tr_str = i2p::i18n::translate(std::forward<TValue>(arg));
size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward<TArgs>(args)...);
std::string str(size, 0);
std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward<TArgs>(args)...);
return str;
}
/**
* @brief Get translation of string with plural forms
* @param arg String with message in singular form
* @param arg2 String with message in plural form
* @param n Integer, used for selection of form
*/
template<typename TValue, typename TValue2>
std::string ntr (TValue&& arg, TValue2&& arg2, int& n)
{
return i2p::i18n::translate(std::forward<TValue>(arg), std::forward<TValue2>(arg2), std::forward<int>(n));
}
/**
* @brief Get translation of string with plural forms and format it
* @param arg String with message in singular form
* @param arg2 String with message in plural form
* @param n Integer, used for selection of form
* @param args Array of arguments for string formatting
*/
template<typename TValue, typename TValue2, typename... TArgs>
std::string ntr (TValue&& arg, TValue2&& arg2, int& n, TArgs&&... args)
{
std::string tr_str = i2p::i18n::translate(std::forward<TValue>(arg), std::forward<TValue2>(arg2), std::forward<int>(n));
size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward<TArgs>(args)...);
std::string str(size, 0);
std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward<TArgs>(args)...);
return str;
return i2p::i18n::translate(std::forward<TArgs>(args)...);
}
#endif // __I18N_H__

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2023, The PurpleI2P Project
* Copyright (c) 2021-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -9,12 +9,60 @@
#ifndef __I18N_LANGS_H__
#define __I18N_LANGS_H__
#include "I18N.h"
namespace i2p
{
namespace i18n
{
class Locale
{
public:
Locale (
const std::string& language,
const std::map<std::string, std::string>& strings,
const std::map<std::string, std::vector<std::string>>& plurals,
std::function<int(int)> formula
): m_Language (language), m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { };
// Get activated language name for webconsole
std::string GetLanguage() const
{
return m_Language;
}
std::string GetString (const std::string& arg) const
{
const auto it = m_Strings.find(arg);
if (it == m_Strings.end())
{
return arg;
}
else
{
return it->second;
}
}
std::string GetPlural (const std::string& arg, const std::string& arg2, const int& n) const
{
const auto it = m_Plurals.find(arg2);
if (it == m_Plurals.end()) // not found, fallback to english
{
return n == 1 ? arg : arg2;
}
else
{
int form = m_Formula(n);
return it->second[form];
}
}
private:
const std::string m_Language;
const std::map<std::string, std::string> m_Strings;
const std::map<std::string, std::vector<std::string>> m_Plurals;
std::function<int(int)> m_Formula;
};
struct langData
{
std::string LocaleName; // localized name
@@ -23,23 +71,15 @@ namespace i18n
};
// Add localization here with language name as namespace
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace chinese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace czech { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace french { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace italian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace polish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace portuguese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace spanish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace swedish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace turkish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace uzbek { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace french { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace uzbek { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
/**
* That map contains international language name lower-case, name in it's language and it's code
@@ -47,21 +87,13 @@ namespace i18n
static std::map<std::string, langData> languages
{
{ "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} },
{ "armenian", {"hայերէն", "hy", i2p::i18n::armenian::GetLocale} },
{ "chinese", {"简体字", "zh-CN", i2p::i18n::chinese::GetLocale} },
{ "czech", {"čeština", "cs", i2p::i18n::czech::GetLocale} },
{ "armenian", {"հայերէն", "hy", i2p::i18n::armenian::GetLocale} },
{ "english", {"English", "en", i2p::i18n::english::GetLocale} },
{ "french", {"Français", "fr", i2p::i18n::french::GetLocale} },
{ "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} },
{ "italian", {"Italiano", "it", i2p::i18n::italian::GetLocale} },
{ "polish", {"Polski", "pl", i2p::i18n::polish::GetLocale} },
{ "portuguese", {"Português", "pt", i2p::i18n::portuguese::GetLocale} },
{ "russian", {"Русский язык", "ru", i2p::i18n::russian::GetLocale} },
{ "spanish", {"Español", "es", i2p::i18n::spanish::GetLocale} },
{ "swedish", {"Svenska", "sv", i2p::i18n::swedish::GetLocale} },
{ "turkish", {"Türk dili", "tr", i2p::i18n::turkish::GetLocale} },
{ "turkmen", {"Türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
{ "ukrainian", {"Украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} },
{ "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} },
{ "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
{ "ukrainian", {"украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} },
{ "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} },
};

View File

@@ -1,223 +0,0 @@
/*
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Italian localization file
namespace i2p
{
namespace i18n
{
namespace italian // language namespace
{
// language name in lowercase
static std::string language = "italian";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "in costruzione"},
{"failed", "fallito"},
{"expiring", "in scadenza"},
{"established", "stabilita"},
{"unknown", "sconosciuto"},
{"exploratory", "esplorativo"},
{"Purple I2P Webconsole", "Terminale web Purple I2P"},
{"<b>i2pd</b> webconsole", "Terminal web <b>i2pd</b>"},
{"Main page", "Pagina principale"},
{"Router commands", "Comandi router"},
{"Local Destinations", "Destinazioni locali"},
{"LeaseSets", "LeaseSets"},
{"Tunnels", "Tunnel"},
{"Transit Tunnels", "Tunnel di transito"},
{"Transports", "Trasporti"},
{"I2P tunnels", "Tunnel I2P"},
{"SAM sessions", "Sessioni SAM"},
{"ERROR", "ERRORE"},
{"OK", "OK"},
{"Testing", "Testando"},
{"Firewalled", "Protetto da firewall"},
{"Unknown", "Sconosciuto"},
{"Proxy", "Proxy"},
{"Mesh", "Mesh"},
{"Clock skew", "Orologio disallineato"},
{"Offline", "Disconnesso"},
{"Symmetric NAT", "NAT simmetrico"},
{"Full cone NAT", "Cono completo NAT"},
{"No Descriptors", "Nessun descrittore"},
{"Uptime", "In funzione da"},
{"Network status", "Stato della rete"},
{"Network status v6", "Stato della rete v6"},
{"Stopping in", "Arresto in"},
{"Family", "Famiglia"},
{"Tunnel creation success rate", "Percentuale di tunnel creati con successo"},
{"Total tunnel creation success rate", "Percentuale di successo totale nella creazione del tunnel"},
{"Received", "Ricevuti"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Inviati"},
{"Transit", "Transitati"},
{"Data path", "Percorso dati"},
{"Hidden content. Press on text to see.", "Contenuto nascosto. Premi sul testo per vedere."},
{"Router Ident", "Identificativo del router"},
{"Router Family", "Famiglia del router"},
{"Router Caps", "Limiti del router"},
{"Version", "Versione"},
{"Our external address", "Il nostro indirizzo esterno"},
{"supported", "supportato"},
{"Routers", "Router"},
{"Floodfills", "Floodfill"},
{"Client Tunnels", "Tunnel client"},
{"Services", "Servizi"},
{"Enabled", "Abilitato"},
{"Disabled", "Disabilitato"},
{"Encrypted B33 address", "Indirizzo criptato B33"},
{"Address registration line", "Linea di registrazione indirizzo"},
{"Domain", "Dominio"},
{"Generate", "Genera"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Nota:</b> la stringa risultante può essere utilizzata solo per registrare domini 2LD (example.i2p). Per registrare i sottodomini, si prega di utilizzare i2pd-tools."},
{"Address", "Indirizzo"},
{"Type", "Tipologia"},
{"EncType", "Tipo di crittografia"},
{"Expire LeaseSet", "Scadenza LeaseSet"},
{"Inbound tunnels", "Tunnel in entrata"},
{"%dms", "%dms"},
{"Outbound tunnels", "Tunnel in uscita"},
{"Tags", "Tag"},
{"Incoming", "In entrata"},
{"Outgoing", "In uscita"},
{"Destination", "Destinazione"},
{"Amount", "Quantità"},
{"Incoming Tags", "Tag in entrata"},
{"Tags sessions", "Sessioni dei tag"},
{"Status", "Stato"},
{"Local Destination", "Destinazione locale"},
{"Streams", "Flussi"},
{"Close stream", "Interrompi il flusso"},
{"Such destination is not found", "Questa destinazione non è stata trovata"},
{"I2CP session not found", "Sessione I2CP non trovata"},
{"I2CP is not enabled", "I2CP non è abilitato"},
{"Invalid", "Invalido"},
{"Store type", "Tipologia di archivio"},
{"Expires", "Scade"},
{"Non Expired Leases", "Lease non scaduti"},
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "Data di fine"},
{"floodfill mode is disabled", "la modalità floodfill è disabilitata"},
{"Queue size", "Dimensione della coda"},
{"Run peer test", "Esegui il test dei peer"},
{"Reload tunnels configuration", "Ricarica la configurazione dei tunnel"},
{"Decline transit tunnels", "Rifiuta tunnel di transito"},
{"Accept transit tunnels", "Accetta tunnel di transito"},
{"Cancel graceful shutdown", "Annulla l'interruzione controllata"},
{"Start graceful shutdown", "Avvia l'interruzione controllata"},
{"Force shutdown", "Forza l'arresto"},
{"Reload external CSS styles", "Ricarica gli stili CSS esterni"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Nota:</b> qualsiasi azione effettuata qui non è persistente e non modifica i file di configurazione."},
{"Logging level", "Livello di log"},
{"Transit tunnels limit", "Limite di tunnel di transito"},
{"Change", "Modifica"},
{"Change language", "Modifica linguaggio"},
{"no transit tunnels currently built", "Attualmente non ci sono tunnel di transito instaurati"},
{"SAM disabled", "SAM disabilitato"},
{"no sessions currently running", "Attualmente non ci sono sessioni attive"},
{"SAM session not found", "Sessione SAM non trovata"},
{"SAM Session", "Sessione SAM"},
{"Server Tunnels", "Tunnel server"},
{"Client Forwards", "Client di inoltro"},
{"Server Forwards", "Server di inoltro"},
{"Unknown page", "Pagina sconosciuta"},
{"Invalid token", "Token non valido"},
{"SUCCESS", "SUCCESSO"},
{"Stream closed", "Flusso terminato"},
{"Stream not found or already was closed", "Il flusso non è stato trovato oppure è già stato terminato"},
{"Destination not found", "Destinazione non trovata"},
{"StreamID can't be null", "Lo StreamID non può essere null"},
{"Return to destination page", "Ritorna alla pagina di destinazione"},
{"You will be redirected in %d seconds", "Sarai reindirizzato tra %d secondi"},
{"LeaseSet expiration time updated", "Tempo di scadenza LeaseSet aggiornato"},
{"LeaseSet is not found or already expired", "LeaseSet non trovato o già scaduto"},
{"Transit tunnels count must not exceed %d", "Il conteggio dei tunnel di transito non deve superare %d"},
{"Back to commands list", "Ritorna alla lista dei comandi"},
{"Register at reg.i2p", "Registra a reg.i2p"},
{"Description", "Descrizione"},
{"A bit information about service on domain", "Alcune informazioni riguardo il servizio sul dominio"},
{"Submit", "Invia"},
{"Domain can't end with .b32.i2p", "I domini non possono terminare con .b32.i2p"},
{"Domain must end with .i2p", "I domini devono terminare con .i2p"},
{"Unknown command", "Comando sconosciuto"},
{"Command accepted", "Comando accettato"},
{"Proxy error", "Errore del proxy"},
{"Proxy info", "Informazioni del proxy"},
{"Proxy error: Host not found", "Errore del proxy: Host non trovato"},
{"Remote host not found in router's addressbook", "L'host remoto non è stato trovato nella rubrica del router"},
{"You may try to find this host on jump services below", "Si può provare a trovare questo host sui servizi di salto qui sotto"},
{"Invalid request", "Richiesta non valida"},
{"Proxy unable to parse your request", "Il proxy non è in grado di elaborare la tua richiesta"},
{"Addresshelper is not supported", "Addresshelper non è supportato"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'host %s è <font color=red>già nella rubrica del router</font>. <b>Attenzione: la fonte di questo URL potrebbe essere dannosa!</b> Fai clic qui per aggiornare il record: <a href=\"%s%s%s&update=true\">Continua</a>."},
{"Addresshelper forced update rejected", "Aggiornamento forzato dell'helper degli indirizzi rifiutato"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Per aggiungere host <b>%s</b> nella rubrica del router, clicca qui: <a href=\"%s%s%s\">Continua</a>."},
{"Addresshelper request", "Richiesta di indirizzo helper"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "L'host %s viene aggiunto alla rubrica del router dall'helper. Fai clic qui per procedere: <a href=\"%s\">Continua</a>."},
{"Addresshelper adding", "Aggiunta di Addresshelper"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'host %s è <font color=red>già nella rubrica del router</font>. Clicca qui per aggiornare il record: <a href=\"%s%s%s&update=true\">Continua</a>."},
{"Addresshelper update", "Aggiornamento dell'helper degli indirizzi"},
{"Invalid request URI", "URI della richiesta non valido"},
{"Can't detect destination host from request", "Impossibile determinare l'host di destinazione dalla richiesta"},
{"Outproxy failure", "Fallimento del proxy di uscita"},
{"Bad outproxy settings", "Impostazioni errate del proxy di uscita"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Host %s non all'interno della rete I2P, ma il proxy di uscita non è abilitato"},
{"Unknown outproxy URL", "URL del proxy di uscita sconosciuto"},
{"Cannot resolve upstream proxy", "Impossibile identificare il flusso a monte del proxy"},
{"Hostname is too long", "Il nome dell'host è troppo lungo"},
{"Cannot connect to upstream SOCKS proxy", "Impossibile connettersi al flusso a monte del proxy SOCKS"},
{"Cannot negotiate with SOCKS proxy", "Impossibile negoziare con il proxy SOCKS"},
{"CONNECT error", "Errore di connessione"},
{"Failed to connect", "Connessione fallita"},
{"SOCKS proxy error", "Errore del proxy SOCKS"},
{"Failed to send request to upstream", "Invio della richiesta a monte non riuscito"},
{"No reply from SOCKS proxy", "Nessuna risposta dal proxy SOCKS"},
{"Cannot connect", "Impossibile connettersi"},
{"HTTP out proxy not implemented", "Proxy HTTP di uscita non implementato"},
{"Cannot connect to upstream HTTP proxy", "Impossibile connettersi al flusso a monte del proxy HTTP"},
{"Host is down", "L'host è offline"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Impossibile creare la connessione all'host richiesto, probabilmente è offline. Riprova più tardi."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d giorno", "%d giorni"}},
{"%d hours", {"%d ora", "%d ore"}},
{"%d minutes", {"%d minuto", "%d minuti"}},
{"%d seconds", {"%d secondo", "%d secondi"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

@@ -1,59 +0,0 @@
/*
* Copyright (c) 2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Polish localization file
namespace i2p
{
namespace i18n
{
namespace polish // language namespace
{
// language name in lowercase
static std::string language = "polish";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return (n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
}
static std::map<std::string, std::string> strings
{
{"building", "Kompilowanie"},
{"failed", "nieudane"},
{"expiring", "wygasający"},
{"established", "ustanowiony"},
{"Main page", "Strona główna"},
{"Router commands", "Komendy routera"},
{"Tunnels", "Tunele"},
{"OK", "Ok"},
{"Uptime", "Czas pracy"},
{"Sent", "Wysłane"},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"", {"", "", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

@@ -1,223 +0,0 @@
/*
* Copyright (c) 2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Portuguese localization file
namespace i2p
{
namespace i18n
{
namespace portuguese // language namespace
{
// language name in lowercase
static std::string language = "portuguese";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "construindo"},
{"failed", "falhou"},
{"expiring", "expirando"},
{"established", "estabelecido"},
{"unknown", "desconhecido"},
{"exploratory", "exploratório"},
{"Purple I2P Webconsole", "Webconsole Purple I2P"},
{"<b>i2pd</b> webconsole", "webconsole <b>i2pd</b>"},
{"Main page", "Página Principal"},
{"Router commands", "Comandos do Roteador"},
{"Local Destinations", "Destinos Locais"},
{"LeaseSets", "LeaseSets"},
{"Tunnels", "Túneis"},
{"Transit Tunnels", "Túneis de Trânsito"},
{"Transports", "Transportes"},
{"I2P tunnels", "Túneis I2P"},
{"SAM sessions", "Sessões do SAM"},
{"ERROR", "ERRO"},
{"OK", "OK"},
{"Testing", "Testando"},
{"Firewalled", "Sob Firewall"},
{"Unknown", "Desconhecido"},
{"Proxy", "Proxy"},
{"Mesh", "Malha"},
{"Clock skew", "Defasagem do Relógio"},
{"Offline", "Desligado"},
{"Symmetric NAT", "NAT Simétrico"},
{"Full cone NAT", "Full cone NAT"},
{"No Descriptors", "Sem Descritores"},
{"Uptime", "Tempo Ativo"},
{"Network status", "Estado da rede"},
{"Network status v6", "Estado da rede v6"},
{"Stopping in", "Parando em"},
{"Family", "Família"},
{"Tunnel creation success rate", "Taxa de sucesso na criação de túneis"},
{"Total tunnel creation success rate", "Taxa total de sucesso na criação de túneis"},
{"Received", "Recebido"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Enviado"},
{"Transit", "Trânsito"},
{"Data path", "Diretório dos dados"},
{"Hidden content. Press on text to see.", "Conteúdo oculto. Clique no texto para revelar."},
{"Router Ident", "Identidade do Roteador"},
{"Router Family", "Família do Roteador"},
{"Router Caps", "Limites do Roteador"},
{"Version", "Versão"},
{"Our external address", "Nosso endereço externo"},
{"supported", "suportado"},
{"Routers", "Roteadores"},
{"Floodfills", "Modo Inundação"},
{"Client Tunnels", "Túneis de Clientes"},
{"Services", "Serviços"},
{"Enabled", "Ativado"},
{"Disabled", "Desativado"},
{"Encrypted B33 address", "Endereço B33 criptografado"},
{"Address registration line", "Linha de cadastro de endereço"},
{"Domain", "Domínio"},
{"Generate", "Gerar"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Nota: </b>A string resultante só pode ser usada para registrar domínios 2LD (exemplo.i2p). Para registrar subdomínios por favor utilize o i2pd-tools."},
{"Address", "Endereço"},
{"Type", "Tipo"},
{"EncType", "Tipo de Criptografia"},
{"Expire LeaseSet", "Expirar LeaseSet"},
{"Inbound tunnels", "Túneis de Entrada"},
{"%dms", "%dms"},
{"Outbound tunnels", "Túneis de Saída"},
{"Tags", "Etiquetas"},
{"Incoming", "Entradas"},
{"Outgoing", "Saídas"},
{"Destination", "Destinos"},
{"Amount", "Quantidade"},
{"Incoming Tags", "Etiquetas de Entrada"},
{"Tags sessions", "Sessões de etiquetas"},
{"Status", "Estado"},
{"Local Destination", "Destinos Locais"},
{"Streams", "Fluxos"},
{"Close stream", "Fechar fluxo"},
{"Such destination is not found", "Tal destino não foi encontrado"},
{"I2CP session not found", "Sessão do I2CP não encontrada"},
{"I2CP is not enabled", "I2CP não está ativado"},
{"Invalid", "Inválido"},
{"Store type", "Tipo de armazenamento"},
{"Expires", "Expira em"},
{"Non Expired Leases", "Sessões não expiradas"},
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "Data final"},
{"floodfill mode is disabled", "Mode de inundação está desativado"},
{"Queue size", "Tamanho da fila"},
{"Run peer test", "Executar teste de peers"},
{"Reload tunnels configuration", "Recarregar a configuração dos túneis"},
{"Decline transit tunnels", "Negar túneis de trânsito"},
{"Accept transit tunnels", "Aceitar túneis de trânsito"},
{"Cancel graceful shutdown", "Cancelar desligamento gracioso"},
{"Start graceful shutdown", "Iniciar desligamento gracioso"},
{"Force shutdown", "Forçar desligamento"},
{"Reload external CSS styles", "Recarregar estilos CSS externos"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b> Nota: </b> Qualquer ação feita aqui não será permanente e não altera os seus arquivos de configuração."},
{"Logging level", "Nível de registro"},
{"Transit tunnels limit", "Limite de túneis de trânsito"},
{"Change", "Mudar"},
{"Change language", "Trocar idioma"},
{"no transit tunnels currently built", "Nenhum túnel de trânsito construido no momento"},
{"SAM disabled", "SAM desativado"},
{"no sessions currently running", "Nenhuma sessão funcionando no momento"},
{"SAM session not found", "Nenhuma sessão do SAM encontrada"},
{"SAM Session", "Sessão do SAM"},
{"Server Tunnels", "Túneis de Servidor"},
{"Client Forwards", "Túneis de Cliente"},
{"Server Forwards", "Encaminhamentos de Servidor"},
{"Unknown page", "Página desconhecida"},
{"Invalid token", "Token Inválido"},
{"SUCCESS", "SUCESSO"},
{"Stream closed", "Fluxo fechado"},
{"Stream not found or already was closed", "Fluxo não encontrado ou já encerrado"},
{"Destination not found", "Destino não encontrado"},
{"StreamID can't be null", "StreamID não pode ser nulo"},
{"Return to destination page", "Retornar para à página de destino"},
{"You will be redirected in %d seconds", "Você será redirecionado em %d segundos"},
{"LeaseSet expiration time updated", "Tempo de validade do LeaseSet atualizado"},
{"LeaseSet is not found or already expired", "LeaseSet não foi encontrado ou já expirou"},
{"Transit tunnels count must not exceed %d", "A contagem de túneis de trânsito não deve exceder %d"},
{"Back to commands list", "Voltar para a lista de comandos"},
{"Register at reg.i2p", "Registrar na reg.i2p"},
{"Description", "Descrição"},
{"A bit information about service on domain", "Algumas informações sobre o serviço no domínio"},
{"Submit", "Enviar"},
{"Domain can't end with .b32.i2p", "O domínio não pode terminar com .b32.i2p"},
{"Domain must end with .i2p", "O domínio não pode terminar com .i2p"},
{"Unknown command", "Comando desconhecido"},
{"Command accepted", "Comando aceito"},
{"Proxy error", "Erro no proxy"},
{"Proxy info", "Informações do proxy"},
{"Proxy error: Host not found", "Erro no proxy: Host não encontrado"},
{"Remote host not found in router's addressbook", "O host remoto não foi encontrado no livro de endereços do roteador"},
{"You may try to find this host on jump services below", "Você pode tentar encontrar este host nos jump services abaixo"},
{"Invalid request", "Requisição inválida"},
{"Proxy unable to parse your request", "O proxy foi incapaz de processar a sua requisição"},
{"Addresshelper is not supported", "O Auxiliar de Endereços não é suportado"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "O host %s já <font color=red>está no catálogo de endereços do roteador</font>. <b>Cuidado: a fonte desta URL pode ser perigosa!</b> Clique aqui para atualizar o registro: <a href=\"%s%s%s&update=true\">Continuar</a>."},
{"Addresshelper forced update rejected", "A atualização forçada do Auxiliar de Endereços foi rejeitada"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Para adicionar o host <b> %s </b> ao catálogo de endereços do roteador, clique aqui: <a href='%s%s%s'>Continuar </a>."},
{"Addresshelper request", "Requisição do Auxiliar de Endereços"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "O host %s foi adicionado ao catálogo de endereços do roteador por um auxiliar. Clique aqui para proceder: <a href='%s'> Continuar </a>."},
{"Addresshelper adding", "Auxiliar de Endereço adicionando"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "O host %s já <font color=red>está no catálogo de endereços do roteador </font>. Clique aqui para atualizar o registro: <a href=\"%s%s%s&update=true\">Continuar</a>."},
{"Addresshelper update", "Atualização do Auxiliar de Endereços"},
{"Invalid request URI", "A URI de requisição é inválida"},
{"Can't detect destination host from request", "Incapaz de detectar o host de destino da requisição"},
{"Outproxy failure", "Falha no outproxy"},
{"Bad outproxy settings", "Configurações ruins de outproxy"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "O host %s não está dentro da rede I2P, mas o outproxy não está ativado"},
{"Unknown outproxy URL", "URL de outproxy desconhecida"},
{"Cannot resolve upstream proxy", "Não é possível resolver o proxy de entrada"},
{"Hostname is too long", "O hostname é muito longo"},
{"Cannot connect to upstream SOCKS proxy", "Não é possível se conectar ao proxy SOCKS de entrada"},
{"Cannot negotiate with SOCKS proxy", "Não é possível negociar com o proxy SOCKS"},
{"CONNECT error", "Erro de CONEXÃO"},
{"Failed to connect", "Falha ao conectar"},
{"SOCKS proxy error", "Erro no proxy SOCKS"},
{"Failed to send request to upstream", "Falha ao enviar requisição para o fluxo de entrada"},
{"No reply from SOCKS proxy", "Sem resposta do proxy SOCKS"},
{"Cannot connect", "Impossível conectar"},
{"HTTP out proxy not implemented", "proxy de saída HTTP não implementado"},
{"Cannot connect to upstream HTTP proxy", "Não é possível conectar ao proxy HTTP de entrada"},
{"Host is down", "Host está desligado"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Não é possível se conectar ao host requisitado, talvez ele esteja for do ar. Por favor, tente novamente mais tarde."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d Dia", "%d Dias"}},
{"%d hours", {"%d hora", "%d horas"}},
{"%d minutes", {"%d minuto", "%d minutos"}},
{"%d seconds", {"%d Segundo", "%d segundos"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2023, The PurpleI2P Project
* Copyright (c) 2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,16 +31,15 @@ namespace russian // language namespace
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f КиБ"},
{"%.2f MiB", "%.2f МиБ"},
{"%.2f GiB", "%.2f ГиБ"},
{"KiB", "КиБ"},
{"MiB", "МиБ"},
{"GiB", "ГиБ"},
{"building", "строится"},
{"failed", "неудачный"},
{"expiring", "истекает"},
{"established", "работает"},
{"unknown", "неизвестно"},
{"exploratory", "исследовательский"},
{"Purple I2P Webconsole", "Веб-консоль Purple I2P"},
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
{"Main page", "Главная"},
{"Router commands", "Команды роутера"},
@@ -58,20 +57,18 @@ namespace russian // language namespace
{"Unknown", "Неизвестно"},
{"Proxy", "Прокси"},
{"Mesh", "MESH-сеть"},
{"Error", "Ошибка"},
{"Clock skew", "Не точное время"},
{"Offline", "Оффлайн"},
{"Symmetric NAT", "Симметричный NAT"},
{"Full cone NAT", "Full cone NAT"},
{"No Descriptors", "Нет дескрипторов"},
{"Uptime", "В сети"},
{"Network status", "Сетевой статус"},
{"Network status v6", "Сетевой статус v6"},
{"Stopping in", "Остановка через"},
{"Family", "Семейство"},
{"Tunnel creation success rate", "Успешно построенных туннелей"},
{"Total tunnel creation success rate", "Общий процент успешно построенных туннелей"},
{"Received", "Получено"},
{"%.2f KiB/s", "%.2f КиБ/с"},
{"KiB/s", "КиБ/с"},
{"Sent", "Отправлено"},
{"Transit", "Транзит"},
{"Data path", "Путь к данным"},
@@ -96,9 +93,8 @@ namespace russian // language namespace
{"Address", "Адрес"},
{"Type", "Тип"},
{"EncType", "ТипШифр"},
{"Expire LeaseSet", "Просрочить Лизсет"},
{"Inbound tunnels", "Входящие туннели"},
{"%dms", "%dмс"},
{"ms", "мс"},
{"Outbound tunnels", "Исходящие туннели"},
{"Tags", "Теги"},
{"Incoming", "Входящие"},
@@ -111,7 +107,6 @@ namespace russian // language namespace
{"Local Destination", "Локальное назначение"},
{"Streams", "Стримы"},
{"Close stream", "Закрыть стрим"},
{"Such destination is not found", "Такая точка назначения не найдена"},
{"I2CP session not found", "I2CP сессия не найдена"},
{"I2CP is not enabled", "I2CP не включен"},
{"Invalid", "Некорректный"},
@@ -121,10 +116,9 @@ namespace russian // language namespace
{"Gateway", "Шлюз"},
{"TunnelID", "ID туннеля"},
{"EndDate", "Заканчивается"},
{"floodfill mode is disabled", "режим флудфила отключен"},
{"not floodfill", "не флудфил"},
{"Queue size", "Размер очереди"},
{"Run peer test", "Запустить тестирование"},
{"Reload tunnels configuration", "Перезагрузить конфигурацию туннелей"},
{"Decline transit tunnels", "Отклонять транзитные туннели"},
{"Accept transit tunnels", "Принимать транзитные туннели"},
{"Cancel graceful shutdown", "Отменить плавную остановку"},
@@ -152,10 +146,8 @@ namespace russian // language namespace
{"Destination not found", "Точка назначения не найдена"},
{"StreamID can't be null", "StreamID не может быть пустым"},
{"Return to destination page", "Вернуться на страницу точки назначения"},
{"You will be redirected in %d seconds", "Вы будете переадресованы через %d секунд"},
{"LeaseSet expiration time updated", "Время действия LeaseSet обновлено"},
{"LeaseSet is not found or already expired", "Лизсет не найден или время действия уже истекло"},
{"Transit tunnels count must not exceed %d", "Число транзитных туннелей не должно превышать %d"},
{"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
{"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
{"Back to commands list", "Вернуться к списку команд"},
{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
{"Description", "Описание"},
@@ -163,6 +155,7 @@ namespace russian // language namespace
{"Submit", "Отправить"},
{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
{"Such destination is not found", "Такая точка назначения не найдена"},
{"Unknown command", "Неизвестная команда"},
{"Command accepted", "Команда принята"},
{"Proxy error", "Ошибка прокси"},
@@ -172,33 +165,32 @@ namespace russian // language namespace
{"You may try to find this host on jump services below", "Вы можете попробовать найти узел через джамп сервисы ниже"},
{"Invalid request", "Некорректный запрос"},
{"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"},
{"Addresshelper is not supported", "Addresshelper не поддерживается"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Узел %s <font color=red>уже в адресной книге роутера</font>. <b>Будьте осторожны: источник данной ссылки может быть вредоносным!</b> Нажмите здесь, чтобы обновить запись: <a href=\"%s%s%s&update=true\">Продолжить</a>."},
{"Addresshelper forced update rejected", "Принудительное обновление через Addresshelper отклонено"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Чтобы добавить узел <b>%s</b> в адресную книгу роутера, нажмите здесь: <a href=\"%s%s%s\"родолжить</a>."},
{"Addresshelper request", "Запрос добавления Addresshelper"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Узел %s добавлен в адресную книгу роутера через хелпер. Нажмите здесь, чтобы продолжить: <a href=\"%s\">Продолжить</a>."},
{"Addresshelper adding", "Добавление Addresshelper"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Узел %s <font color=red>уже в адресной книге роутера</font>. Нажмите здесь, чтобы обновить запись: <a href=\"%s%s%s&update=true\">Продолжить</a>."},
{"Addresshelper update", "Обновление записи через Addresshelper"},
{"Invalid request URI", "Некорректный URI запроса"},
{"addresshelper is not supported", "addresshelper не поддерживается"},
{"Host", "Узел"},
{"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"},
{"Click here to proceed:", "Нажмите здесь, чтобы продолжить:"},
{"Continue", "Продолжить"},
{"Addresshelper found", "Найден addresshelper"},
{"already in router's addressbook", "уже в адресной книге роутера"},
{"Click here to update record:", "Нажмите здесь, чтобы обновить запись:"},
{"invalid request uri", "некорректный URI запроса"},
{"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"},
{"Outproxy failure", "Ошибка внешнего прокси"},
{"Bad outproxy settings", "Некорректные настройки внешнего прокси"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Узел %s не в I2P сети, но внешний прокси не включен"},
{"Unknown outproxy URL", "Неизвестный URL внешнего прокси"},
{"Cannot resolve upstream proxy", "Не удается определить вышестоящий прокси"},
{"Hostname is too long", "Имя хоста слишком длинное"},
{"Cannot connect to upstream SOCKS proxy", "Не удалось подключиться к вышестоящему SOCKS прокси серверу"},
{"Cannot negotiate with SOCKS proxy", "Не удается договориться с вышестоящим SOCKS прокси"},
{"bad outproxy settings", "некорректные настройки внешнего прокси"},
{"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"},
{"unknown outproxy url", "неизвестный URL внешнего прокси"},
{"cannot resolve upstream proxy", "не удается определить вышестоящий прокси"},
{"hostname too long", "имя хоста слишком длинное"},
{"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"},
{"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"},
{"CONNECT error", "Ошибка CONNECT запроса"},
{"Failed to connect", "Не удалось соединиться"},
{"SOCKS proxy error", "Ошибка SOCKS прокси"},
{"Failed to send request to upstream", "Не удалось отправить запрос вышестоящему прокси серверу"},
{"No reply from SOCKS proxy", "Нет ответа от SOCKS прокси сервера"},
{"Cannot connect", "Не удалось подключиться"},
{"HTTP out proxy not implemented", "Поддержка внешнего HTTP прокси сервера не реализована"},
{"Cannot connect to upstream HTTP proxy", "Не удалось подключиться к вышестоящему HTTP прокси серверу"},
{"Failed to Connect", "Не удалось подключиться"},
{"socks proxy error", "ошибка SOCKS прокси"},
{"failed to send request to upstream", "не удалось отправить запрос вышестоящему прокси"},
{"No Reply From socks proxy", "Нет ответа от SOCKS прокси сервера"},
{"cannot connect", "не удалось подключиться"},
{"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"},
{"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"},
{"Host is down", "Узел недоступен"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному узлу, возможно он не в сети. Попробуйте повторить запрос позже."},
{"", ""},
@@ -206,10 +198,10 @@ namespace russian // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d день", "%d дня", "%d дней"}},
{"%d hours", {"%d час", "%d часа", "%d часов"}},
{"%d minutes", {"%d минуту", "%d минуты", "%d минут"}},
{"%d seconds", {"%d секунду", "%d секунды", "%d секунд"}},
{"days", {"день", "дня", "дней"}},
{"hours", {"час", "часа", "часов"}},
{"minutes", {"минуту", "минуты", "минут"}},
{"seconds", {"секунду", "секунды", "секунд"}},
{"", {"", "", ""}},
};

View File

@@ -1,204 +0,0 @@
/*
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Spanish localization file
namespace i2p
{
namespace i18n
{
namespace spanish // language namespace
{
// language name in lowercase
static std::string language = "spanish";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "pendiente"},
{"failed", "fallido"},
{"expiring", "expiró"},
{"established", "establecido"},
{"unknown", "desconocido"},
{"exploratory", "exploratorio"},
{"Purple I2P Webconsole", "Consola web de Purple I2P"},
{"<b>i2pd</b> webconsole", "Consola web de <b>i2pd</b>"},
{"Main page", "Inicio"},
{"Router commands", "Comandos de enrutador"},
{"Local Destinations", "Destinos locales"},
{"LeaseSets", "LeaseSets"},
{"Tunnels", "Túneles"},
{"Transit Tunnels", "Túneles de Tránsito"},
{"Transports", "Transportes"},
{"I2P tunnels", "Túneles I2P"},
{"SAM sessions", "Sesiones SAM"},
{"ERROR", "ERROR"},
{"OK", "VALE"},
{"Testing", "Probando"},
{"Firewalled", "Con cortafuegos"},
{"Unknown", "Desconocido"},
{"Proxy", "Proxy"},
{"Mesh", "Malla"},
{"Clock skew", "Reloj desfasado"},
{"Offline", "Desconectado"},
{"Symmetric NAT", "NAT simétrico"},
{"Uptime", "Tiempo en línea"},
{"Network status", "Estado de red"},
{"Network status v6", "Estado de red v6"},
{"Stopping in", "Parando en"},
{"Family", "Familia"},
{"Tunnel creation success rate", "Tasa de éxito de creación de túneles"},
{"Received", "Recibido"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Enviado"},
{"Transit", "Tránsito"},
{"Data path", "Ruta de datos"},
{"Hidden content. Press on text to see.", "Contenido oculto. Presione para ver."},
{"Router Ident", "Ident del Enrutador"},
{"Router Family", "Familia de enrutador"},
{"Router Caps", "Atributos del Enrutador"},
{"Version", "Versión"},
{"Our external address", "Nuestra dirección externa"},
{"supported", "soportado"},
{"Routers", "Enrutadores"},
{"Floodfills", "Inundaciones"},
{"Client Tunnels", "Túneles de cliente"},
{"Services", "Servicios"},
{"Enabled", "Activado"},
{"Disabled", "Desactivado"},
{"Encrypted B33 address", "Dirección encriptada B33"},
{"Address registration line", "Línea para registrar direcciones"},
{"Domain", "Dominio"},
{"Generate", "Generar"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Nota:</b> la cadena resultante solo se puede usar para registrar dominios 2LD (ejemplo.i2p). Para registrar subdominios, por favor utilice i2pd-tools."},
{"Address", "Dirección"},
{"Type", "Tipo"},
{"EncType", "TipoEncrip"},
{"Inbound tunnels", "Túneles entrantes"},
{"%dms", "%dms"},
{"Outbound tunnels", "Túneles salientes"},
{"Tags", "Etiquetas"},
{"Incoming", "Entrante"},
{"Outgoing", "Saliente"},
{"Destination", "Destino"},
{"Amount", "Cantidad"},
{"Incoming Tags", "Etiquetas entrantes"},
{"Tags sessions", "Sesiones de etiquetas"},
{"Status", "Estado"},
{"Local Destination", "Destino Local"},
{"Streams", "Flujos"},
{"Close stream", "Cerrar flujo"},
{"I2CP session not found", "Sesión I2CP no encontrada"},
{"I2CP is not enabled", "I2CP no está activado"},
{"Invalid", "Inválido"},
{"Store type", "Tipo de almacenamiento"},
{"Expires", "Caduca"},
{"Non Expired Leases", "Sesiones No Expiradas"},
{"Gateway", "Puerta de enlace"},
{"TunnelID", "TunnelID"},
{"EndDate", "FechaVenc"},
{"Queue size", "Tamaño de cola"},
{"Run peer test", "Ejecutar prueba de par"},
{"Decline transit tunnels", "Rechazar túneles de tránsito"},
{"Accept transit tunnels", "Aceptar túneles de tránsito"},
{"Cancel graceful shutdown", "Cancelar apagado con gracia"},
{"Start graceful shutdown", "Iniciar apagado con gracia"},
{"Force shutdown", "Forzar apagado"},
{"Reload external CSS styles", "Recargar estilos CSS externos"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Nota:</b> cualquier acción hecha aquí no es persistente y no cambia tus archivos de configuración."},
{"Logging level", "Nivel de registro de errores"},
{"Transit tunnels limit", "Límite de túneles de tránsito"},
{"Change", "Cambiar"},
{"Change language", "Cambiar idioma"},
{"no transit tunnels currently built", "no hay túneles de tránsito actualmente construidos"},
{"SAM disabled", "SAM desactivado"},
{"no sessions currently running", "no hay sesiones ejecutándose ahora"},
{"SAM session not found", "Sesión SAM no encontrada"},
{"SAM Session", "Sesión SAM"},
{"Server Tunnels", "Túneles de Servidor"},
{"Client Forwards", "Redirecciones de Cliente"},
{"Server Forwards", "Redirecciones de Servidor"},
{"Unknown page", "Página desconocida"},
{"Invalid token", "Token inválido"},
{"SUCCESS", "ÉXITO"},
{"Stream closed", "Transmisión cerrada"},
{"Stream not found or already was closed", "No se encontró la transmisión o ya se cerró"},
{"Destination not found", "Destino no encontrado"},
{"StreamID can't be null", "StreamID no puede ser nulo"},
{"Return to destination page", "Volver a la página de destino"},
{"Back to commands list", "Volver a lista de comandos"},
{"Register at reg.i2p", "Registrar en reg.i2p"},
{"Description", "Descripción"},
{"A bit information about service on domain", "Un poco de información sobre el servicio en el dominio"},
{"Submit", "Enviar"},
{"Domain can't end with .b32.i2p", "El dominio no puede terminar con .b32.i2p"},
{"Domain must end with .i2p", "El dominio debe terminar con .i2p"},
{"Such destination is not found", "No se encontró el destino"},
{"Unknown command", "Comando desconocido"},
{"Command accepted", "Comando aceptado"},
{"Proxy error", "Error de proxy"},
{"Proxy info", "Información del proxy"},
{"Proxy error: Host not found", "Error de proxy: Host no encontrado"},
{"Remote host not found in router's addressbook", "Servidor remoto no encontrado en la libreta de direcciones del enrutador"},
{"You may try to find this host on jump services below", "Puede intentar encontrar este dominio en los siguientes servicios de salto"},
{"Invalid request", "Solicitud inválida"},
{"Proxy unable to parse your request", "Proxy no puede procesar su solicitud"},
{"Invalid request URI", "URI de solicitud inválida"},
{"Can't detect destination host from request", "No se puede detectar el host de destino de la solicitud"},
{"Outproxy failure", "Fallo en el proxy saliente"},
{"Bad outproxy settings", "Configuración de outproxy incorrecta"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Dominio %s no está dentro de la red I2P, pero el proxy de salida no está activado"},
{"Unknown outproxy URL", "URL de proxy outproxy desconocido"},
{"Cannot resolve upstream proxy", "No se puede resolver el proxy de upstream"},
{"Hostname is too long", "Nombre de dominio muy largo"},
{"Cannot connect to upstream SOCKS proxy", "No se puede conectar al proxy SOCKS principal"},
{"Cannot negotiate with SOCKS proxy", "No se puede negociar con el proxy SOCKS"},
{"CONNECT error", "Error de CONNECT"},
{"Failed to connect", "Error al conectar"},
{"SOCKS proxy error", "Error de proxy SOCKS"},
{"Failed to send request to upstream", "No se pudo enviar petición al principal"},
{"No reply from SOCKS proxy", "Sin respuesta del proxy SOCKS"},
{"Cannot connect", "No se puede conectar"},
{"HTTP out proxy not implemented", "Proxy externo HTTP no implementado"},
{"Cannot connect to upstream HTTP proxy", "No se puede conectar al proxy HTTP principal"},
{"Host is down", "Servidor caído"},
{"Can't create connection to requested host, it may be down. Please try again later.", "No se puede crear la conexión al servidor solicitado, puede estar caído. Intente de nuevo más tarde."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d día", "%d días"}},
{"%d hours", {"%d hora", "%d horas"}},
{"%d minutes", {"%d minuto", "%d minutos"}},
{"%d seconds", {"%d segundo", "%d segundos"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

@@ -1,220 +0,0 @@
/*
* Copyright (c) 2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Swedish localization file
namespace i2p
{
namespace i18n
{
namespace swedish // language namespace
{
// language name in lowercase
static std::string language = "swedish";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "bygger"},
{"failed", "misslyckad"},
{"expiring", "utgår"},
{"established", "upprättad"},
{"unknown", "okänt"},
{"exploratory", "utforskande"},
{"Purple I2P Webconsole", "Purple I2P Webbkonsoll"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b>-Webbkonsoll"},
{"Main page", "Huvudsida"},
{"Router commands", "Routerkommandon"},
{"Local Destinations", "Lokala Platser"},
{"LeaseSets", "Hyresuppsättningar"},
{"Tunnels", "Tunnlar"},
{"Transit Tunnels", "Förmedlande Tunnlar"},
{"Transports", "Transporter"},
{"I2P tunnels", "I2P-tunnlar"},
{"SAM sessions", "SAM-perioder"},
{"ERROR", "FEL"},
{"OK", "OK"},
{"Testing", "Prövar"},
{"Firewalled", "Bakom Brandvägg"},
{"Unknown", "Okänt"},
{"Proxy", "Proxy"},
{"Mesh", "Mesh"},
{"Clock skew", "Tidsförskjutning"},
{"Offline", "Nedkopplad"},
{"Symmetric NAT", "Symmetrisk NAT"},
{"Full cone NAT", "Full kon NAT"},
{"No Descriptors", "Inga Beskrivningar"},
{"Uptime", "Upptid"},
{"Network status", "Nätverkstillstånd"},
{"Network status v6", "Nätverkstillstånd v6"},
{"Stopping in", "Avstängd om"},
{"Family", "Familj"},
{"Tunnel creation success rate", "Andel framgångsrika tunnlar"},
{"Received", "Mottaget"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Skickat"},
{"Transit", "Förmedlat"},
{"Data path", "Sökväg"},
{"Hidden content. Press on text to see.", "Dolt innehåll. Tryck för att visa."},
{"Router Ident", "Routeridentitet"},
{"Router Family", "Routerfamilj"},
{"Router Caps", "Routerbegränsningar"},
{"Version", "Version"},
{"Our external address", "Vår externa adress"},
{"supported", "stöds"},
{"Routers", "Routrar"},
{"Floodfills", "Översvämningsfyllare"},
{"Client Tunnels", "Klienttunnlar"},
{"Services", "Tjänster"},
{"Enabled", "Påslaget"},
{"Disabled", "Avslaget"},
{"Encrypted B33 address", "Krypterad B33-Adress"},
{"Address registration line", "Adressregistreringsrad"},
{"Domain", "Domän"},
{"Generate", "Skapa"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Uppmärksamma:</b> den resulterande strängen kan enbart användas för att registrera 2LD-domäner (exempel.i2p). För att registrera underdomäner, vänligen använd i2pd-tools."},
{"Address", "Adress"},
{"Type", "Typ"},
{"EncType", "EncTyp"},
{"Inbound tunnels", "Ingående Tunnlar"},
{"%dms", "%dms"},
{"Outbound tunnels", "Utgående Tunnlar"},
{"Tags", "Taggar"},
{"Incoming", "Ingående"},
{"Outgoing", "Utgående"},
{"Destination", "Plats"},
{"Amount", "Mängd"},
{"Incoming Tags", "Ingående Taggar"},
{"Tags sessions", "Tagg-perioder"},
{"Status", "Tillstånd"},
{"Local Destination", "Lokal Plats"},
{"Streams", "Strömmar"},
{"Close stream", "Stäng strömmen"},
{"Such destination is not found", "En sådan plats hittas ej"},
{"I2CP session not found", "I2CP-period hittades inte"},
{"I2CP is not enabled", "I2CP är inte påslaget"},
{"Invalid", "Ogiltig"},
{"Store type", "Lagringstyp"},
{"Expires", "Utgångsdatum"},
{"Non Expired Leases", "Ickeutgångna Hyresuppsättningar"},
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "EndDate"},
{"floodfill mode is disabled", "Floodfill läget är inaktiverat"},
{"Queue size", "Köstorlek"},
{"Run peer test", "Utför utsiktstest"},
{"Reload tunnels configuration", "Ladda om tunnelkonfiguration"},
{"Decline transit tunnels", "Avvisa förmedlande tunnlar"},
{"Accept transit tunnels", "Tillåt förmedlande tunnlar"},
{"Cancel graceful shutdown", "Avbryt välvillig avstängning"},
{"Start graceful shutdown", "Påbörja välvillig avstängning"},
{"Force shutdown", "Tvingad avstängning"},
{"Reload external CSS styles", "Ladda om externa CSS-stilar"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Uppmärksamma:</b> inga ändringar här är beständiga eller påverkar dina inställningsfiler."},
{"Logging level", "Protokollförningsnivå"},
{"Transit tunnels limit", "Begränsa förmedlande tunnlar"},
{"Change", "Ändra"},
{"Change language", "Ändra språk"},
{"no transit tunnels currently built", "inga förmedlande tunnlar har byggts"},
{"SAM disabled", "SAM avslaget"},
{"no sessions currently running", "inga perioder igång"},
{"SAM session not found", "SAM-perioder hittades ej"},
{"SAM Session", "SAM-period"},
{"Server Tunnels", "Värdtunnlar"},
{"Client Forwards", "Klientförpassningar"},
{"Server Forwards", "Värdförpassningar"},
{"Unknown page", "Okänd sida"},
{"Invalid token", "Ogiltig polett"},
{"SUCCESS", "FRAMGÅNG"},
{"Stream closed", "Ström stängd"},
{"Stream not found or already was closed", "Strömmen hittades inte eller var redan avslutad"},
{"Destination not found", "Plats hittades ej"},
{"StreamID can't be null", "Ström-ID kan inte vara null"},
{"Return to destination page", "Återvänd till platssidan"},
{"You will be redirected in %d seconds", "Du omdirigeras inom %d sekunder"},
{"Transit tunnels count must not exceed %d", "Förmedlande tunnlar får inte överstiga %d"},
{"Back to commands list", "Tillbaka till kommandolistan"},
{"Register at reg.i2p", "Registrera vid reg.i2p"},
{"Description", "Beskrivning"},
{"A bit information about service on domain", "Ett stycke information om domänens tjänst"},
{"Submit", "Skicka"},
{"Domain can't end with .b32.i2p", "Domänen får inte sluta med .b32.i2p"},
{"Domain must end with .i2p", "Domänen måste sluta med .i2p"},
{"Unknown command", "Okänt kommando"},
{"Command accepted", "Kommando accepterades"},
{"Proxy error", "Proxyfel"},
{"Proxy info", "Proxyinfo"},
{"Proxy error: Host not found", "Proxyfel: Värden hittades ej"},
{"Remote host not found in router's addressbook", "Främmande värd hittades inte i routerns adressbok"},
{"You may try to find this host on jump services below", "Du kan försöka att hitta värden genom hopptjänsterna nedan"},
{"Invalid request", "Ogiltig förfrågan"},
{"Proxy unable to parse your request", "Proxyt kan inte behandla din förfrågan"},
{"Addresshelper is not supported", "Adresshjälparen stöds ej"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Värd %s är <font color=red>redan i routerns adressbok</font>. <b>Var försiktig: källan till denna URL kan vara skadlig!</b> Klicka här för att uppdatera registreringen: <a href=\"%s%s%s&update=true\">Fortsätt</a>."},
{"Addresshelper forced update rejected", "Tvingad uppdatering av adresshjälparen nekad"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "För att lägga till värd <b>%s</b> i routerns adressbok, klicka här: <a href=\"%s%s%s\">Fortsätt</a>."},
{"Addresshelper request", "Adresshjälpare förfrågan"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Värd %s tillagd i routerns adressbok från hjälparen. Klicka här för att fortsätta: <a href=\"%s\">Fortsätt</a>."},
{"Addresshelper adding", "Adresshjälpare tilläggning"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Värd %s är <font color=red>redan i routerns adressbok</font>. Klicka här för att uppdatera registreringen: <a href=\"%s%s%s&update=true\">Fortsätt</a>."},
{"Addresshelper update", "Adresshjälpare uppdatering"},
{"Invalid request URI", "Ogiltig förfrågnings-URI"},
{"Can't detect destination host from request", "Kan inte upptäcka platsvärden från förfrågan"},
{"Outproxy failure", "Utproxyfel"},
{"Bad outproxy settings", "Ogiltig utproxyinställning"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Värd %s är inte inom I2P-näverket, men utproxy är inte påslaget"},
{"Unknown outproxy URL", "okänt Utproxy-URL"},
{"Cannot resolve upstream proxy", "Hittar inte uppströmsproxyt"},
{"Hostname is too long", "Värdnamnet är för långt"},
{"Cannot connect to upstream SOCKS proxy", "Kan inte ansluta till uppström SOCKS-proxy"},
{"Cannot negotiate with SOCKS proxy", "Kan inte förhandla med SOCKSproxyt"},
{"CONNECT error", "CONNECT-fel"},
{"Failed to connect", "Anslutningen misslyckades"},
{"SOCKS proxy error", "SOCKSproxyfel"},
{"Failed to send request to upstream", "Förfrågan uppströms kunde ej skickas"},
{"No reply from SOCKS proxy", "Fick inget svar från SOCKSproxyt"},
{"Cannot connect", "Kan inte ansluta"},
{"HTTP out proxy not implemented", "HTTP-Utproxy ej implementerat"},
{"Cannot connect to upstream HTTP proxy", "Kan inte ansluta till uppströms HTTP-proxy"},
{"Host is down", "Värden är nere"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Kan inte ansluta till värden, den kan vara nere. Vänligen försök senare."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d dag", "%d dagar"}},
{"%d hours", {"%d timme", "%d timmar"}},
{"%d minutes", {"%d minut", "%d minuter"}},
{"%d seconds", {"%d sekund", "%d sekunder"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

@@ -1,114 +0,0 @@
/*
* Copyright (c) 2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Turkish localization file
namespace i2p
{
namespace i18n
{
namespace turkish // language namespace
{
// language name in lowercase
static std::string language = "turkish";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "kuruluyor"},
{"failed", "başarısız"},
{"expiring", "süresi geçiyor"},
{"established", "kurulmuş"},
{"unknown", "bilinmeyen"},
{"Purple I2P Webconsole", "Mor I2P Webkonsolu"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> webkonsolu"},
{"Main page", "Ana sayfa"},
{"Router commands", "Router komutları"},
{"Local Destinations", "Yerel Hedefler"},
{"Tunnels", "Tüneller"},
{"Transit Tunnels", "Transit Tünelleri"},
{"Transports", "Taşıma"},
{"I2P tunnels", "I2P tünelleri"},
{"SAM sessions", "SAM oturumları"},
{"ERROR", "HATA"},
{"OK", "TAMAM"},
{"Testing", "Test ediliyor"},
{"Firewalled", "Güvenlik Duvarı Kısıtlaması"},
{"Unknown", "Bilinmeyen"},
{"Proxy", "Proxy"},
{"Clock skew", "Saat sorunu"},
{"Offline", "Çevrimdışı"},
{"Symmetric NAT", "Simetrik NAT"},
{"Full cone NAT", "Full cone NAT"},
{"No Descriptors", "Tanımlayıcı Yok"},
{"Uptime", "Bağlantı süresi"},
{"Network status", "Ağ durumu"},
{"Network status v6", "Ağ durumu v6"},
{"Family", "Aile"},
{"Tunnel creation success rate", "Tünel oluşturma başarı oranı"},
{"Received", "Alındı"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Gönderildi"},
{"Transit", "Transit"},
{"Data path", "Veri yolu"},
{"Hidden content. Press on text to see.", "Gizlenmiş içerik. Görmek için yazıya tıklayınız."},
{"Router Family", "Router Familyası"},
{"Decline transit tunnels", "Transit tünellerini reddet"},
{"Accept transit tunnels", "Transit tünellerini kabul et"},
{"Cancel graceful shutdown", "Düzgün durdurmayı iptal Et"},
{"Start graceful shutdown", "Düzgün durdurmayı başlat"},
{"Force shutdown", "Durdurmaya zorla"},
{"Reload external CSS styles", "Harici CSS stilini yeniden yükle"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Not:</b> burada yapılan ayarların hiçbiri kalıcı değildir ve ayar dosyalarınızı değiştirmez."},
{"Logging level", "Kayıt tutma seviyesi"},
{"Transit tunnels limit", "Transit tünel limiti"},
{"Change", "Değiştir"},
{"Change language", "Dil değiştir"},
{"no transit tunnels currently built", "kurulmuş bir transit tüneli bulunmamakta"},
{"SAM disabled", "SAM devre dışı"},
{"no sessions currently running", "hiçbir oturum şu anda çalışmıyor"},
{"SAM session not found", "SAM oturumu bulunamadı"},
{"SAM Session", "SAM oturumu"},
{"Server Tunnels", "Sunucu Tünelleri"},
{"Unknown page", "Bilinmeyen sayfa"},
{"Invalid token", "Geçersiz token"},
{"SUCCESS", "BAŞARILI"},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d gün", "%d gün"}},
{"%d hours", {"%d saat", "%d saat"}},
{"%d minutes", {"%d dakika", "%d dakika"}},
{"%d seconds", {"%d saniye", "%d saniye"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

Some files were not shown because too many files have changed in this diff Show More