Merge branch 'master' into unix

This commit is contained in:
Alexey Sokolov
2025-04-18 23:46:16 +01:00
1234 changed files with 149930 additions and 10349 deletions
+6 -27
View File
@@ -4,48 +4,27 @@
# TODO: test msvc
version: 0.0.0.0.1-branch-{branch}-build-{build}
clone_depth: 10
environment:
matrix:
- cygwin_url: https://cygwin.com/setup-x86_64.exe
build_with: cmake
- cygwin_url: https://cygwin.com/setup-x86.exe
build_with: cmake
- cygwin_url: https://cygwin.com/setup-x86_64.exe
build_with: autoconf
- cygwin_url: https://cygwin.com/setup-x86.exe
build_with: autoconf
install:
- ps: Invoke-WebRequest $env:cygwin_url -OutFile c:\cygwin-setup.exe
- ps: Invoke-WebRequest https://cygwin.com/setup-x86_64.exe -OutFile c:\cygwin-setup.exe
# libcrypt-devel is needed only on x86_64 and only for modperl... probably some dependency problem.
- c:\cygwin-setup.exe --quiet-mode --no-shortcuts --no-startmenu --no-desktop --upgrade-also --only-site --site http://cygwin.mirror.constant.com/ --root c:\cygwin-root --local-package-dir c:\cygwin-setup-cache --packages automake,gcc-g++,make,pkg-config,wget,openssl-devel,libicu-devel,zlib-devel,libcrypt-devel,perl,python3-devel,swig,libsasl2-devel,libQt5Core-devel,cmake,libboost-devel,gettext-devel
- c:\cygwin-setup.exe --quiet-mode --no-shortcuts --no-startmenu --no-desktop --upgrade-also --only-site --site http://cygwin.mirror.constant.com/ --root c:\cygwin-root --local-package-dir c:\cygwin-setup-cache --packages gcc-g++,make,pkg-config,wget,libssl-devel,libicu-devel,zlib-devel,libcrypt-devel,perl,python3-devel,swig,libsasl2-devel,libQt5Core-devel,cmake,libboost-devel,gettext-devel,libargon2-devel
- c:\cygwin-root\bin\sh -lc "echo Hi"
- c:\cygwin-root\bin\sh -lc "uname -a"
- c:\cygwin-root\bin\sh -lc "cat /proc/cpuinfo"
- c:\cygwin-root\bin\sh -lc "cat /proc/meminfo"
- c:\cygwin-root\bin\sh -lc "cygcheck -s -v > $APPVEYOR_BUILD_FOLDER/cygcheck.log 2>&1"
- ps: Push-AppveyorArtifact cygcheck.log
- ps: |
if ($env:build_with -eq "cmake") {
$env:cfg_suffix = ".sh"
$env:unittest = "unittest"
$env:inttest = "inttest"
} else {
$env:cfg_suffix = ""
$env:unittest = "test"
$env:inttest = "test2"
}
# stdin is broken at AppVeyor, so we open it explicitly as /dev/null
build_script:
- git submodule update --init
- c:\cygwin-root\bin\sh -lc "cd $APPVEYOR_BUILD_FOLDER; ./autogen.sh < /dev/null"
- mkdir build
- c:\cygwin-root\bin\sh -lc "cd $APPVEYOR_BUILD_FOLDER/build; ../configure$cfg_suffix --enable-charset --enable-zlib --enable-openssl --enable-perl --enable-python --enable-cyrus < /dev/null; result=$?; if [[ $build_with == cmake ]]; then cmake --system-information > config.log; fi; appveyor PushArtifact config.log; exit $result"
- c:\cygwin-root\bin\sh -lc "cd $APPVEYOR_BUILD_FOLDER/build; env ZNC_QT_VER=5 ../configure --enable-charset --enable-zlib --enable-openssl --enable-perl --enable-python --enable-cyrus --enable-argon < /dev/null; result=$?; cmake --system-information > config.log; appveyor PushArtifact config.log; exit $result"
- c:\cygwin-root\bin\sh -lc "cd $APPVEYOR_BUILD_FOLDER/build; make VERBOSE=1 -j2 < /dev/null"
- c:\cygwin-root\bin\sh -lc "cd $APPVEYOR_BUILD_FOLDER/build; make install < /dev/null"
- c:\cygwin-root\bin\sh -lc "znc --version"
# fix fork()
- c:\cygwin-root\bin\sh -lc "find /usr/local/lib/znc -iname '*.dll' -o -iname '*.so' | tee /tmp/files-to-rebase"
- c:\cygwin-root\bin\sh -lc "rebaseall -v -T /tmp/files-to-rebase"
- c:\cygwin-root\bin\sh -lc "rebase -s -v $(cat /tmp/files-to-rebase)"
test_script:
- c:\cygwin-root\bin\sh -lc "cd $APPVEYOR_BUILD_FOLDER/build; make VERBOSE=1 $unittest < /dev/null"
- c:\cygwin-root\bin\sh -lc "cd $APPVEYOR_BUILD_FOLDER/build; make VERBOSE=1 $inttest < /dev/null"
- c:\cygwin-root\bin\sh -lc "cd $APPVEYOR_BUILD_FOLDER/build; make VERBOSE=1 unittest < /dev/null"
- c:\cygwin-root\bin\sh -lc "cd $APPVEYOR_BUILD_FOLDER/build; env ZNC_QT_VER=5 make VERBOSE=1 inttest < /dev/null"
+121
View File
@@ -0,0 +1,121 @@
#!groovy
// This script is run daily by https://jenkins.znc.in/ to:
// * upload new English strings to https://crowdin.com/project/znc-bouncer
// * download new translations
// * commits results to ZNC repo
import groovy.json.JsonSlurper;
import groovy.json.JsonOutput;
def upstream_user = 'znc'
def upstream_repo = 'znc'
def my_user = 'znc-jenkins'
def my_repo = 'znc'
def branches = ['master', '1.9.x']
def pr_mode = false
timestamps {
node {
timeout(time: 30, unit: 'MINUTES') {
stage('WsCleanup') {
step([$class: 'WsCleanup'])
}
def tasks = [:]
def crowdin_cli = "java -jar ${tool 'crowdin-cli'}/crowdin-cli.jar"
def crowdin_cli_suffix = "--config .ci/crowdin.yml"
for (def branch in branches) {
def upstream_branch = branch
def my_branch = "l10n_${branch}"
tasks[branch] = {
stage(upstream_branch) {
dir(upstream_branch) {
stage("Checkout ${upstream_branch}") {
checkout([$class: 'GitSCM', branches: [[name: "*/${upstream_branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'SubmoduleOption', recursiveSubmodules: true]], userRemoteConfigs: [[credentialsId: '6ef10f80-20dc-4661-af45-52a6e1e15749', name: 'upstream', url: "git@github.com:${upstream_user}/${upstream_repo}.git"]]])
}
stage("Prepare strings for ${upstream_branch}") {
dir("build") {
sh "cmake .."
sh 'make translation'
}
sh 'rm -rf build/'
sh 'git status'
}
stage("Crowdin for ${upstream_branch}") {
withCredentials([string(credentialsId: '11c7e2b4-f990-4670-98a4-c89d2a5a2f43', variable: 'CROWDIN_API_KEY')]) {
withEnv(['CROWDIN_BASE_PATH='+pwd()]) {
sh "$crowdin_cli upload sources --branch ${upstream_branch} ${crowdin_cli_suffix}"
// sh "$crowdin_cli upload translations --branch ${upstream_branch} ${crowdin_cli_suffix}"
sh "$crowdin_cli download --branch ${upstream_branch} ${crowdin_cli_suffix}"
}
def headers = [[maskValue: true, name: 'Authorization', value: "Bearer ${env.CROWDIN_API_KEY}"], [maskValue: false, name: 'User-Agent', value: 'https://github.com/znc/znc/blob/master/.ci/Jenkinsfile.crowdin']]
def contributors = httpRequest consoleLogResponseBody: true, customHeaders: headers, url: "https://crowdin.com/api/v2/projects/289533/members?limit=500"
writeFile file: 'contributors.tmp', text: contributors.content
}
sh 'LANG=C.UTF-8 find . -name "*.po" -exec msgfilter -i "{}" -o "{}.replacement" .ci/cleanup-po.pl ";"'
sh 'find . -name "*.po" -exec mv "{}.replacement" "{}" ";"'
sh '.ci/crowdin-contributors.py < contributors.tmp'
sh 'rm contributors.tmp'
}
stage("Push ${upstream_branch}") {
sh 'git config user.name "ZNC-Jenkins"'
sh 'git config user.email jenkins@znc.in'
sh 'git status'
def git_status_short = sh (script: 'git status --short', returnStdout: true)
def modified_locales = sh (
script: 'git status --short | grep -o -E "[^ ]+\\.po$" | sed "s/.po//g" | grep -o -E "[a-z]{2}_[A-Z]{2}$" | sort -u | tr "\\n" " " | sed -E "s/ $//"',
returnStdout: true
)
sh 'git add .'
try {
sh "git commit -m 'Update translations from Crowdin for ${modified_locales}'"
} catch(e) {
echo 'No changes found'
return
}
if (!pr_mode) {
sshagent(credentials: ['baf2df74-935d-40e5-b20f-076e92fa3e9f']) {
sh "git push upstream HEAD:refs/heads/${upstream_branch}"
}
return
}
// Create pull request if it doesn't exist yet
// Note: the following code hasn't been executed for long time, so probably nothing here works anymore, APIs might have changed, etc.
sh "git remote add my git@github.com:${my_user}/${my_repo}.git"
sshagent(credentials: ['6ef10f80-20dc-4661-af45-52a6e1e15749']) {
sh "git push my HEAD:refs/heads/${my_branch} -f"
}
withCredentials([string(credentialsId: '7a2546ae-8a29-4eab-921c-6a4803456dce', variable: 'GITHUB_OAUTH_KEY')]) {
def headers = [[maskValue: true, name: 'Authorization', value: "token ${env.GITHUB_OAUTH_KEY}"], [maskValue: false, name: 'Accept', value: 'application/vnd.github.v3+json'], [maskValue: false, name: 'User-Agent', value: 'https://github.com/znc/znc/blob/master/.ci/Jenkinsfile.crowdin']]
def pulls = httpRequest consoleLogResponseBody: true, customHeaders: headers, url: "https://api.github.com/repos/${upstream_user}/${upstream_repo}/pulls?head=${my_user}:${my_branch}&base=${upstream_branch}"
pulls = new JsonSlurper().parseText(pulls.content)
if (!pulls) {
def bodyContents = "Crowdin: https://crowdin.com/project/znc-bouncer\nJenkins Build: ${env.BUILD_URL}"
bodyContents += "\n\nModified locales:\n${modified_locales}"
bodyContents += "\n\n<details><summary>Modified files</summary>${git_status_short}</details>"
httpRequest consoleLogResponseBody: true,
customHeaders: headers,
url: "https://api.github.com/repos/${upstream_user}/${upstream_repo}/pulls",
httpMode: 'POST',
requestBody: JsonOutput.toJson(
[
head: my_user + ':' + my_branch,
base: upstream_branch,
title: "Update translations in ${upstream_branch} (${modified_locales})",
body: bodyContents
]
)
}
}
}
}
}
}
}
parallel tasks
}
}
}
// vim: set ts=2 sw=2 et:
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env perl
use strict;
use warnings;
use v5.10;
local $/;
my $text = <>;
if ($ENV{MSGFILTER_MSGID}) {
print $text;
} else {
for (split(/^/, $text)) {
next if /^PO-Revision-Date:/;
s/^Last-Translator: \K.*/Various people/;
print;
}
}
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
import json
import sys
array = []
data = json.load(sys.stdin)
for user in data['data']:
user = user['data']
if user['fullName']:
array.append('* {} ({})'.format(user['username'], user['fullName']))
else:
array.append('* ' + user['username'])
array.sort(key=lambda x: x.lower())
sys.stdout = open('TRANSLATORS.md', 'wt', encoding='utf-8')
print('These people helped translating ZNC to various languages:')
print()
for u in array:
print(u)
print()
print('Generated from https://crowdin.com/project/znc-bouncer')
+13
View File
@@ -0,0 +1,13 @@
# https://crowdin.com/project/znc-bouncer
project_id: 289533
preserve_hierarchy: true
api_token_env: CROWDIN_API_KEY
base_path_env: CROWDIN_BASE_PATH
files:
- source: /src/po/znc.pot
translation: /src/po/znc.%locale_with_underscore%.po
update_option: update_as_unapproved
- source: "/modules/po/*.pot"
translation: /modules/po/%file_name%.%locale_with_underscore%.po
update_option: update_as_unapproved
@@ -7,7 +7,7 @@ doxygen
cd "$HOME"
git clone --depth=1 --branch=gh-pages github:znc/docs.git gh-pages || exit 1
cd "$TRAVIS_BUILD_DIR/doc/html/"
cd "$GITHUB_WORKSPACE/doc/html/"
mv ~/gh-pages/.git ./
echo docs.znc.in > CNAME
git add -A
@@ -28,9 +28,9 @@ if [[ ! -f ~/docs_need_commit ]]; then
fi
git commit -F- <<EOF
Latest docs on successful travis build $TRAVIS_BUILD_NUMBER
Latest docs on successful CI build $GITHUB_RUN_NUMBER
ZNC commit $TRAVIS_COMMIT
ZNC commit $GITHUB_SHA
EOF
git push origin gh-pages
View File
+7 -1
View File
@@ -6,10 +6,16 @@ ignore:
- /modules/modpython/znc_core.py
- /modules/modperl/ZNC.pm
fixes:
- "usr/local/lib/znc/::modules/" # C++ and Python seem to work without this, but Perl needs this.
- "usr/local/lib/znc/::modules/"
- "/usr/local/lib/znc/::modules/"
codecov:
ci:
# Cygwin fails integration test with --coverage enabled, I don't know why
- !appveyor
# FreeBSD doesn't support C++ coverage yet (can't find libprofile_rt.a)
- !jenkins.znc.in
coverage:
status:
project:
default:
threshold: 1%
+2
View File
@@ -0,0 +1,2 @@
.git
build*
+55
View File
@@ -0,0 +1,55 @@
set -x
pwd
ls -la
cpanm --local-lib=~/perl5 local::lib
eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
cpanm --notest Devel::Cover::Report::Clover
pip3 install --user --break-system-packages coverage
export ZNC_MODPERL_COVERAGE=1
#export ZNC_MODPYTHON_COVERAGE=1
case "${CC:-gcc}" in
gcc)
export CXXFLAGS="$CXXFLAGS --coverage"
export LDFLAGS="$LDFLAGS --coverage"
;;
clang)
export CXXFLAGS="$CXXFLAGS -fprofile-instr-generate -fcoverage-mapping"
export LDFLAGS="$LDFLAGS -fprofile-instr-generate"
;;
esac
mkdir build
cd build
../configure --enable-debug --enable-perl --enable-python --enable-tcl --enable-cyrus --enable-charset --enable-argon $CFGFLAGS
cmake --system-information
make -j2 VERBOSE=1
env LLVM_PROFILE_FILE="$PWD/unittest.profraw" make VERBOSE=1 unittest
sudo make install
/usr/local/bin/znc --version
# TODO: use DEVEL_COVER_OPTIONS for https://metacpan.org/pod/Devel::Cover
env LLVM_PROFILE_FILE="$PWD/inttest.profraw" ZNC_MODPERL_COVERAGE_OPTS="-db,$PWD/cover_db" PYTHONWARNINGS=error make VERBOSE=1 inttest
ls -lRa
~/perl5/bin/cover --no-gcov --report=clover
case "${CC:-gcc}" in
gcc)
lcov --directory . --capture --output-file lcov-coverage.txt --ignore-errors mismatch
lcov --list lcov-coverage.txt
;;
clang)
if [[ x$(uname) == xDarwin ]]; then
export PATH=$PATH:/Library/Developer/CommandLineTools/usr/bin
fi
llvm-profdata merge unittest.profraw -o unittest.profdata
llvm-profdata merge inttest.profraw -o inttest.profdata
llvm-cov show -show-line-counts-or-regions -instr-profile=unittest.profdata test/unittest_bin > unittest-cmake-coverage.txt
llvm-cov show -show-line-counts-or-regions -instr-profile=inttest.profdata /usr/local/bin/znc > inttest-znc-coverage.txt
find /usr/local/lib/znc -name '*.so' -or -name '*.bundle' | while read f; do llvm-cov show -show-line-counts-or-regions -instr-profile=inttest.profdata $f > inttest-$(basename $f)-coverage.txt; done
;;
esac
+7
View File
@@ -0,0 +1,7 @@
---
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
+4
View File
@@ -0,0 +1,4 @@
sudo apt-get update
sudo apt-get install -y tcl-dev libsasl2-dev libicu-dev swig qt6-base-dev libboost-locale-dev libperl-dev libargon2-dev cpanminus gettext clang llvm lcov
sudo apt-get upgrade -y
+190
View File
@@ -0,0 +1,190 @@
name: build
on:
- push
- pull_request
jobs:
gcc:
name: GCC
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
submodules: true
- run: source .github/ubuntu_deps.sh
- run: source .github/build.sh
- uses: codecov/codecov-action@v5
with:
name: ${{ github.job }}
- uses: actions/upload-artifact@v4
with:
name: codecov debug results ${{ github.job }}
path: "/tmp/codecov.*.gz"
tarball:
name: Tarball
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
submodules: true
- run: source .github/ubuntu_deps.sh
- run: |
date=$(date +%Y-%m-%d)
./make-tarball.sh --nightly znc-git-$date /tmp/znc-git-$date.tar.gz
tar xvf /tmp/znc-git-$date.tar.gz
cd znc-git-$date
export CFGFLAGS="--with-gtest=$GITHUB_WORKSPACE/third_party/googletest/googletest --with-gmock=$GITHUB_WORKSPACE/third_party/googletest/googlemock --disable-swig"
source $GITHUB_WORKSPACE/.github/build.sh
- uses: actions/upload-artifact@v4
with:
name: znc-tarball
path: /tmp/znc-git*.tar.gz
if-no-files-found: error
- uses: codecov/codecov-action@v5
with:
name: ${{ github.job }}
# can be removed when asan below is fixed
clang:
name: Clang
runs-on: ubuntu-24.04
env:
CXX: clang++
CC: clang
steps:
- uses: actions/checkout@v4
with:
submodules: true
- run: source .github/ubuntu_deps.sh
- run: source .github/build.sh
- uses: codecov/codecov-action@v5
with:
name: ${{ github.job }}
- uses: actions/upload-artifact@v4
with:
name: codecov debug results ${{ github.job }}
path: "/tmp/codecov.*.gz"
#clang_asan:
#name: Clang ASAN
#runs-on: ubuntu-24.04
#env:
#CXX: clang++
#CC: clang
#CXXFLAGS: "-fsanitize=address -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fPIE"
#LDFLAGS: "-fsanitize=address -pie"
#steps:
#- uses: actions/checkout@v4
#with:
#submodules: true
#- run: source .github/ubuntu_deps.sh
#- run: source .github/build.sh
#- uses: codecov/codecov-action@v5
#clang_tsan:
#name: Clang TSAN
#runs-on: ubuntu-24.04
#env:
#CXX: clang++
#CC: clang
#CXXFLAGS: "-fsanitize=thread -O1 -fPIE"
#LDFLAGS: "-fsanitize=thread"
#steps:
#- uses: actions/checkout@v4
#with:
#submodules: true
#- run: source .github/ubuntu_deps.sh
#- run: source .github/build.sh
#- uses: codecov/codecov-action@v5
# TODO: enable
#CXXFLAGS: "-fsanitize=memory -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins"
#LDFLAGS: "-fsanitize=memory"
#CXXFLAGS: "-fsanitize=undefined -O1 -fPIE -fno-sanitize-recover"
#LDFLAGS: "-fsanitize=undefined -pie -fno-sanitize-recover"
macos:
name: macOS
runs-on: macos-latest
env:
# This doesn't make big difference, since it's the same compiler, but we also use this variable to select lcov vs llvm-cov
CXX: clang++
CC: clang
steps:
- uses: actions/checkout@v4
with:
submodules: true
- run: |
brew update
brew install icu4c qt6 gettext pkg-config cpanminus boost argon2 swig
- run: source .github/build.sh
env:
# https://github.com/znc/znc/issues/1937
GTEST_FILTER: "-*Modpython*:LanguagesTests/AllLanguages.ServerDependentCapInModule/1"
- uses: codecov/codecov-action@v5
docker:
name: Docker push
runs-on: ubuntu-latest
needs:
- gcc
- tarball
- clang
steps:
- uses: actions/checkout@v4
with:
submodules: true
- id: tagger
run: |
git fetch --unshallow
echo "::set-output name=describe::$(git describe)"
if [[ "$GITHUB_REF" == refs/heads/master ]]; then
echo "::set-output name=latest::type=raw,latest"
fi
- uses: docker/metadata-action@v5
id: meta
with:
images: zncbouncer/znc-git
tags: |
type=ref,event=branch
type=ref,event=branch,suffix=-${{steps.tagger.outputs.describe}}
${{steps.tagger.outputs.latest}}
- run: echo "${GITHUB_REF#refs/heads/}-${{steps.tagger.outputs.describe}}" > .nightly
- run: cat .nightly
- uses: docker/login-action@v3
if: ${{ github.repository == 'znc/znc' && github.event_name == 'push' }}
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.repository == 'znc/znc' && github.event_name == 'push' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION_EXTRA=+docker-git-
docs:
name: Docs push
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
steps:
- uses: actions/checkout@v4
with:
submodules: true
- run: sudo apt-get update
- run: sudo apt-get install -y doxygen graphviz python3-yaml
- run: echo "$KEY" > ~/znc-github-key
env:
KEY: ${{ secrets.SSH_GITHUB_KEY_FOR_CI_BOT }}
- run: chmod 0600 ~/znc-github-key
- run: mkdir -p ~/.ssh
- run: cp .ci/ssh-config ~/.ssh/config
# It's not travis anymore, but oh well. TODO: fix
- run: git config --global user.email "travis-ci@znc.in"
- run: git config --global user.name "znc-travis"
- run: .ci/generate-docs.sh
+27
View File
@@ -0,0 +1,27 @@
# Fuzzer is configured at https://github.com/google/oss-fuzz/tree/master/projects/znc
name: CIFuzz
on: [pull_request]
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'znc'
dry-run: false
language: c++
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'znc'
fuzz-seconds: 300
dry-run: false
language: c++
- name: Upload Crash
uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts
+48
View File
@@ -0,0 +1,48 @@
name: "CodeQL"
on:
push:
branches: [ 'master', '1.9.x' ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ 'master' ]
schedule:
- cron: '1 14 * * 6'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-24.04
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp', 'javascript', 'python' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
- run: |
source .github/ubuntu_deps.sh
sudo apt-get remove -y qt6-base-dev
sudo apt-get install -y qtbase5-dev
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- run: source .github/build.sh
env:
ZNC_QT_VER: "5"
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
+7 -1
View File
@@ -1,6 +1,12 @@
[submodule "Csocket"]
path = third_party/Csocket
url = https://github.com/jimloco/Csocket.git
url = https://github.com/znc/Csocket
[submodule "third_party/googletest"]
path = third_party/googletest
url = https://github.com/google/googletest
[submodule "docker"]
path = docker
url = https://github.com/znc/znc-docker
[submodule "third_party/cctz"]
path = third_party/cctz
url = https://github.com/google/cctz
+1
View File
@@ -29,3 +29,4 @@ with open('.travis.yml', 'w') as f:
subprocess.check_call(['git checkout -b coverity_scan'], shell=True)
subprocess.check_call(['git commit .travis.yml -m"Automatic coverity scan for {}"'.format(datetime.date.today())], shell=True)
subprocess.check_call(['git push coverity coverity_scan -f'], shell=True)
subprocess.call(['git push coverity master'], shell=True)
+2 -2
View File
@@ -11,11 +11,11 @@ addons:
name: "znc/coverity"
description: "Build submitted via Travis CI"
notification_email: coverity@znc.in
build_command_prepend: "./bootstrap.sh; ./configure --enable-perl --enable-python --enable-tcl --enable-cyrus"
build_command_prepend: "./configure --enable-perl --enable-python --enable-tcl --enable-cyrus"
build_command: "make VERBOSE=1"
branch_pattern: coverity_scan
script:
- /bin/true
sudo: required
dist: trusty
dist: bionic
Binary file not shown.
+66 -70
View File
@@ -1,68 +1,52 @@
language: cpp
env:
global:
# SECRET_KEY, used to push docs to github and to init coverity scans
- secure: "i2f2UVDnyHT/9z0U3XvgTj8eDERvnc1Wk7HpseEjb75JwGzqn/2R+RKHmoSrwK3hFgij2IMxZL19XtHFwMz9t5A/huAAKD74KMMI/QpeZEJ/sjT3CTLcE9HEVDdJOjc7dfLRxb2hZtgvx8clZIMrpeUdPhci8openff30KvXVbg="
# These linux-specific parameters could be moved into matrix.include items, but that's lots of repetition
sudo: required
dist: trusty
dist: bionic
arch: amd64
services:
- docker
# See https://github.com/google/sanitizers/issues/856
group: deprecated-2017Q3
# TODO: add Linux LLVM coverage; clang 3.5.0 on ubuntu trusty is too old.
matrix:
fast_finish: true
include:
- os: linux
dist: xenial
compiler: gcc
env: BUILD_TYPE=normal BUILD_WITH=cmake COVERAGE=gcov
env: BUILD_TYPE=normal
- os: linux
compiler: clang
env: BUILD_TYPE=asan
- os: linux
compiler: clang
env: BUILD_TYPE=tsan
# TODO: enable
# - os: linux
# compiler: clang
# env: BUILD_TYPE=msan
# - os: linux
# compiler: clang
# env: BUILD_TYPE=ubsan
- os: linux
compiler: gcc
env: BUILD_TYPE=normal BUILD_WITH=autoconf COVERAGE=gcov
- os: linux
compiler: clang
env: BUILD_TYPE=asan BUILD_WITH=cmake COVERAGE=no
- os: linux
compiler: clang
env: BUILD_TYPE=tsan BUILD_WITH=cmake COVERAGE=no
env: BUILD_TYPE=normal
arch: arm64
- os: osx
osx_image: xcode7.3 # OS X 10.11
osx_image: xcode9.3 # macOS 10.13
compiler: clang
env: BUILD_TYPE=normal BUILD_WITH=cmake COVERAGE=llvm
- os: osx
osx_image: xcode7.3 # OS X 10.11
compiler: clang
env: BUILD_TYPE=normal BUILD_WITH=autoconf COVERAGE=llvm
- os: osx
osx_image: xcode8.3 # macOS 10.12
compiler: clang
env: BUILD_TYPE=normal BUILD_WITH=cmake COVERAGE=llvm
- os: osx
osx_image: xcode8.3 # macOS 10.12
compiler: clang
env: BUILD_TYPE=normal BUILD_WITH=autoconf COVERAGE=llvm
- os: osx
osx_image: xcode9.1 # macOS 10.12
compiler: clang
env: BUILD_TYPE=normal BUILD_WITH=cmake COVERAGE=llvm
- os: osx
osx_image: xcode9.1 # macOS 10.12
compiler: clang
env: BUILD_TYPE=normal BUILD_WITH=autoconf COVERAGE=llvm
env: BUILD_TYPE=normal
- os: linux
compiler: gcc
env: BUILD_TYPE=tarball BUILD_WITH=cmake COVERAGE=gcov
- os: linux
compiler: gcc
env: BUILD_TYPE=tarball BUILD_WITH=autoconf COVERAGE=gcov
env: BUILD_TYPE=tarball
- stage: deploy
os: linux
env:
# SECRET_KEY, used to push docs to github and to init coverity scans
- secure: "ne14MIcNsUNKjqtgrLHJTHXCUUMKfkV/o4sm2scWYOiIl8s1Hoqnx6mPYIr8qnedIra8fsI7sWVxXLDLd/KMTN9v9WpCwc6Sf45vYtkfrS+rNOr86wOeEbgaxDTsb2UDJhtK0InhhpkipA5jrFzQuMMMEB+JgBQltKV43wmd7Yc="
before_install:
install:
- if [[ "$TRAVIS_REPO_SLUG" == "znc/znc" && "$TRAVIS_PULL_REQUEST" == "false" && "$TRAVIS_BRANCH" == "master" ]]; then ATTEMPT_DEPLOY=yes; else ATTEMPT_DEPLOY=no; fi
- if [[ "$ATTEMPT_DEPLOY" == "yes" ]]; then openssl aes-256-cbc -d -in .travis-github.enc -out ~/znc-github-key -k ${SECRET_KEY}; fi
- if [[ "$ATTEMPT_DEPLOY" == "yes" ]]; then openssl aes-256-cbc -d -salt -pbkdf2 -in .travis-github.enc -out ~/znc-github-key -k ${SECRET_KEY}; fi
- export SECRET_KEY=no
- if [[ "$ATTEMPT_DEPLOY" == "yes" ]]; then sudo apt-get update; fi
- if [[ "$ATTEMPT_DEPLOY" == "yes" ]]; then sudo apt-get install -y doxygen graphviz python3-yaml; fi
@@ -78,71 +62,83 @@ matrix:
- if [[ "$ATTEMPT_DEPLOY" == "yes" ]]; then ./.travis-generate-docs.sh; fi
- if [[ "$ATTEMPT_DEPLOY" == "yes" ]]; then ./.travis-coverity-scan.py; fi
after_success:
- stage: deploy
os: linux
env:
# DOCKER_USERNAME
- secure: "kiR372QH5Srye2beHVamOVLIPeXnDipWfzvzGJEZzbpH+aXsiD+CkbtulCR+XnKpnUAXQTmEc5ts1KjI9MGlxvP1ztxW8HMDGUMF4iFAjgZO8GyAZlH5I7pMEw7D5pn3W9y1LuCW5C9IsDcWnNTJkm32D7N34lLBCTQVw68ooDk="
# DOCKER_PASSWORD
- secure: "FMKQarGQJ/MFXnQQWEnlWMM+XItbDPgm5tzCn4k36AsAB1s1SiQ08wmy2Ys/+kRvnPN3Clpl8P2C8CoRTMJ8WCUYZVmf3HsqvsLdrODyusR5/N1y5eOKWxo+t1qN2Jzt6oIi/ofUZdn5mdzt8yif+ufxoez+2ncZDt5HoB/suHE="
before_install:
install:
- if [[ "$TRAVIS_REPO_SLUG" == "znc/znc" && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ATTEMPT_DEPLOY=yes; else ATTEMPT_DEPLOY=no; fi
- if [[ "$ATTEMPT_DEPLOY" == "yes" ]]; then echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin; fi
- export DOCKER_PASSWORD=no DOCKER_USERNAME=no
script:
- echo "$TRAVIS_BRANCH-$(git describe)" > .nightly
- docker build --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=`git rev-parse HEAD` --build-arg VERSION_EXTRA=+docker-git- -t "zncbouncer/znc-git:$TRAVIS_BRANCH" -t "zncbouncer/znc-git:$TRAVIS_BRANCH-$(git describe)" .
- if [[ "$ATTEMPT_DEPLOY" == "yes" && "$TRAVIS_BRANCH" == "master" ]]; then docker tag "zncbouncer/znc-git:$TRAVIS_BRANCH" zncbouncer/znc-git:latest; fi
- if [[ "$ATTEMPT_DEPLOY" == "yes" ]]; then docker push zncbouncer/znc-git; fi
after_success:
before_install:
- python -c "import fcntl; fcntl.fcntl(1, fcntl.F_SETFL, 0)" # https://github.com/travis-ci/travis-ci/issues/8920
- "echo os: [$TRAVIS_OS_NAME] build: [$BUILD_TYPE]"
- export SECRET_KEY=no
- export CFGFLAGS= MYCXXFLAGS= MYLDFLAGS=
- if [[ "$BUILD_TYPE" == "tarball" ]]; then CFGFLAGS+=" --with-gtest=$TRAVIS_BUILD_DIR/third_party/googletest/googletest --with-gmock=$TRAVIS_BUILD_DIR/third_party/googletest/googlemock --disable-swig"; fi
- if [[ "$BUILD_TYPE" == "asan" ]]; then MYCXXFLAGS+=" -fsanitize=address -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fPIE" MYLDFLAGS+=" -fsanitize=address -pie"; fi
- if [[ "$BUILD_TYPE" == "tsan" ]]; then MYCXXFLAGS+=" -fsanitize=thread -O1 -fPIE" MYLDFLAGS+=" -fsanitize=thread"; fi
- if [[ "$BUILD_WITH" == "cmake" ]]; then CFGSUFFIX=.sh UNITTEST=unittest INTTEST=inttest; else CFGSUFFIX= UNITTEST=test INTTEST=test2; fi
- if [[ "$COVERAGE" == "gcov" ]]; then MYCXXFLAGS+=" --coverage" MYLDFLAGS+=" --coverage"; fi
- if [[ "$COVERAGE" == "llvm" ]]; then MYCXXFLAGS+=" -fprofile-instr-generate -fcoverage-mapping" MYLDFLAGS+=" -fprofile-instr-generate"; fi
# UBSan randomly crashes clang, and very often :(
# CFGFLAGS= MYCXXFLAGS="-fsanitize=undefined -O1 -fPIE -fno-sanitize-recover" MYLDFLAGS="-fsanitize=undefined -pie -fno-sanitize-recover"
- if [[ "$BUILD_TYPE" == "msan" ]]; then MYCXXFLAGS+=" -fsanitize=memory -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins" MYLDFLAGS+=" -fsanitize=memory"; fi
- if [[ "$BUILD_TYPE" == "ubsan" ]]; then MYCXXFLAGS=" -fsanitize=undefined -O1 -fPIE -fno-sanitize-recover" MYLDFLAGS="-fsanitize=undefined -pie -fno-sanitize-recover"; fi
- if [[ "$CC" == "gcc" ]]; then MYCXXFLAGS+=" --coverage" MYLDFLAGS+=" --coverage"; fi
- if [[ "$CC" == "clang" ]]; then MYCXXFLAGS+=" -fprofile-instr-generate -fcoverage-mapping" MYLDFLAGS+=" -fprofile-instr-generate"; fi
install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cat /proc/cpuinfo /proc/meminfo; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then lsb_release -a; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository -y ppa:teward/swig3.0; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository -y ppa:beineri/opt-qt551-trusty; fi # default qt5.2 from trusty doesn't support QByteArray::toStdString()
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_WITH" == "cmake" ]]; then sudo add-apt-repository -y ppa:george-edison55/cmake-3.x; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y libperl-dev tcl-dev libsasl2-dev libicu-dev swig3.0 qt55base libboost-locale-dev; fi
# Clang 3.5 TSan is broken on Travis Ubuntu 14.04. Clang 3.8 seems to work, but only without -pie (https://github.com/google/sanitizers/issues/503)
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "tsan" ]]; then sudo apt-get install -y clang-3.8; export CC=clang-3.8 CXX=clang++-3.8; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then source /opt/qt55/bin/qt55-env.sh; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_WITH" == "cmake" ]]; then sudo apt-get install -y cmake; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then source ~/virtualenv/python3.5/bin/activate; fi # for pip3
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export PKG_CONFIG_PATH="/opt/python/3.5/lib/pkgconfig:$PKG_CONFIG_PATH" LD_LIBRARY_PATH="/opt/python/3.5/lib:$LD_LIBRARY_PATH"; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y libperl-dev tcl-dev libsasl2-dev libicu-dev swig qtbase5-dev libboost-locale-dev python3-pip cpanminus; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y cmake; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib); fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cpanm --notest Devel::Cover::Report::Clover; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export ZNC_MODPERL_COVERAGE=1; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sw_vers; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sysctl -a | grep cpu; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sysctl -a | grep mem; fi
# Something broke in Travis brew making it impossible to update python versions (complaining about nil:NilClass), so remove preinstalled brew and install from scratch
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then rm -rf /usr/local/Cellar/* /usr/local/opt/* /usr/local/share/aclocal; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"; hash -r; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew config; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew list --versions; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install swig python3 icu4c jq openssl qt5 gettext; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$BUILD_WITH" == "cmake" ]]; then brew outdated cmake || brew upgrade cmake; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install swig icu4c jq qt5 gettext python cmake openssl pkg-config; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated python || brew upgrade python; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated cmake || brew upgrade cmake; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew info --json=v1 --installed | jq .; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PKG_CONFIG_PATH="$(brew --prefix qt5)/lib/pkgconfig:$PKG_CONFIG_PATH"; fi
- pip3 install coverage
- pip3 install --user coverage
- export ZNC_MODPYTHON_COVERAGE=1
- "echo pkg-config path: [$PKG_CONFIG_PATH]"
script:
- set -v
- if [[ "$BUILD_TYPE" == "tarball" ]]; then ./make-tarball.sh --nightly znc-git-2015-01-16 /tmp/znc-tarball.tar.gz; fi
- if [[ "$BUILD_TYPE" == "tarball" ]]; then cd /tmp; tar xvf znc-tarball.tar.gz; fi
- if [[ "$BUILD_TYPE" == "tarball" ]]; then cd /tmp/znc-git-2015-01-16; fi
- if [[ "$BUILD_TYPE" != "tarball" && "$BUILD_WITH" != "cmake" ]]; then ./bootstrap.sh; fi
- mkdir build
- cd build
- ../configure$CFGSUFFIX --enable-debug --enable-perl --enable-python --enable-tcl --enable-cyrus --enable-charset $CFGFLAGS CXXFLAGS="$CXXFLAGS $MYCXXFLAGS" LDFLAGS="$LDFLAGS $MYLDFLAGS"
- if [[ "$BUILD_WITH" == "cmake" ]]; then cmake --system-information; else cat config.log; fi
- ../configure.sh --enable-debug --enable-perl --enable-python --enable-tcl --enable-cyrus --enable-charset $CFGFLAGS CXXFLAGS="$CXXFLAGS $MYCXXFLAGS" LDFLAGS="$LDFLAGS $MYLDFLAGS"
- cmake --system-information
- make VERBOSE=1
- env LLVM_PROFILE_FILE="$PWD/unittest.profraw" make VERBOSE=1 $UNITTEST
- env LLVM_PROFILE_FILE="$PWD/unittest.profraw" make VERBOSE=1 unittest
- sudo make install
# TODO: use DEVEL_COVER_OPTIONS for https://metacpan.org/pod/Devel::Cover
- env LLVM_PROFILE_FILE="$PWD/inttest.profraw" ZNC_MODPERL_COVERAGE_OPTS="-db,$PWD/cover_db" make VERBOSE=1 $INTTEST
- env LLVM_PROFILE_FILE="$PWD/inttest.profraw" ZNC_MODPERL_COVERAGE_OPTS="-db,$PWD/cover_db" PYTHONWARNINGS=error make VERBOSE=1 inttest
- /usr/local/bin/znc --version
after_success:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/perl5/bin/cover --no-gcov --report=clover; fi
- |
if [[ "$TRAVIS_OS_NAME" == "osx" && "$COVERAGE" == "llvm" ]]; then
if [[ "$TRAVIS_OS_NAME" == "osx" && "$CC" == "clang" ]]; then
xcrun llvm-profdata merge unittest.profraw -o unittest.profdata
xcrun llvm-profdata merge inttest.profraw -o inttest.profdata
xcrun llvm-cov show -show-line-counts-or-regions -instr-profile=unittest.profdata test/unittest_bin > unittest-cmake-coverage.txt
xcrun llvm-cov show -show-line-counts-or-regions -instr-profile=unittest.profdata unittest > unittest-autoconf-coverage.txt
xcrun llvm-cov show -show-line-counts-or-regions -instr-profile=inttest.profdata /usr/local/bin/znc > inttest-znc-coverage.txt
find /usr/local/lib/znc -name '*.so' -or -name '*.bundle' | while read f; do xcrun llvm-cov show -show-line-counts-or-regions -instr-profile=inttest.profdata $f > inttest-$(basename $f)-coverage.txt; done
fi
+151 -32
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,9 +14,9 @@
# limitations under the License.
#
cmake_minimum_required(VERSION 3.1)
project(ZNC VERSION 1.7.0)
set(ZNC_VERSION 1.7.x)
cmake_minimum_required(VERSION 3.13)
project(ZNC VERSION 1.10.0 LANGUAGES CXX)
set(ZNC_VERSION 1.10.x)
set(append_git_version true)
set(alpha_version "") # e.g. "-rc1"
set(VERSION_EXTRA "" CACHE STRING
@@ -41,12 +41,10 @@ endfunction()
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
include(TestCXX11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED true)
include(TestCXX17)
if(NOT CYGWIN)
# We don't want to use -std=gnu++11 instead of -std=c++11, but among other
# things, -std=c++11 on cygwin defines __STRICT_ANSI__ which makes cygwin
# We don't want to use -std=gnu++17 instead of -std=c++17, but among other
# things, -std=c++17 on cygwin defines __STRICT_ANSI__ which makes cygwin
# not to compile: undefined references to strerror_r, to fdopen, to
# strcasecmp, etc (their declarations in system headers are between ifdef)
set(CMAKE_CXX_EXTENSIONS false)
@@ -57,6 +55,7 @@ include(use_homebrew)
include(GNUInstallDirs)
include(CheckCXXSymbolExists)
include(copy_csocket)
include(CMakePushCheckState)
set(CMAKE_THREAD_PREFER_PTHREAD true)
set(THREADS_PREFER_PTHREAD_FLAG true)
@@ -79,9 +78,28 @@ macro(tristate_option opt help)
endif()
endmacro()
set(ZNC_CMAKE_FIND_DEPS "")
set(zncpubdeps)
tristate_option(OPENSSL "Support SSL")
if(WANT_OPENSSL)
find_package(OpenSSL ${TRISTATE_OPENSSL_REQUIRED})
if(OPENSSL_FOUND)
# SSL_SESSION was made opaque in OpenSSL 1.1.0;
# LibreSSL gained that function later too.
# TODO: maybe remove this check at some point, and stop supporting old
# libssl versions
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_cxx_symbol_exists(SSL_SESSION_get0_cipher openssl/ssl.h
HAVE_SSL_SESSION_get0_cipher)
cmake_pop_check_state()
set(ZNC_CMAKE_FIND_DEPS
"${ZNC_CMAKE_FIND_DEPS}\nfind_dependency(OpenSSL)")
list(APPEND zncpubdeps OpenSSL::SSL)
endif()
endif()
set(HAVE_LIBSSL "${OPENSSL_FOUND}")
@@ -96,23 +114,25 @@ set(HAVE_ZLIB "${ZLIB_FOUND}")
tristate_option(CYRUS "Support authentication with Cyrus")
if(WANT_CYRUS)
pkg_check_modules(CYRUS libsasl2)
pkg_check_modules(CYRUS IMPORTED_TARGET libsasl2)
if(NOT CYRUS_FOUND)
# libsasl2.pc is missing on 2.1.25 which is on ubuntu 14.04
# next ubuntu version has 2.1.26 which has libsasl2.pc
#
# osx (as of El Capitan) doesn't have it either...
set(_old_cmake_required_libraries "${CMAKE_REQUIRED_LIBRARIES}")
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} -lsasl2)
# sys/types.h here is workaround for sasl 2.1.26:
# https://github.com/znc/znc/issues/1243
# https://lists.andrew.cmu.edu/pipermail/cyrus-sasl/2012-December/002572.html
# https://cgit.cyrus.foundation/cyrus-sasl/commit/include/sasl.h?id=2f740223fa1820dd71e6ab0e50d4964760789209
check_cxx_symbol_exists(sasl_server_init "sys/types.h;sasl/sasl.h"
CYRUS_HARDCODED)
set(CMAKE_REQUIRED_LIBRARIES "${_old_cmake_required_libraries}")
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_LIBRARIES -lsasl2)
# sys/types.h here is workaround for sasl 2.1.26:
# https://github.com/znc/znc/issues/1243
# https://lists.andrew.cmu.edu/pipermail/cyrus-sasl/2012-December/002572.html
# https://cgit.cyrus.foundation/cyrus-sasl/commit/include/sasl.h?id=2f740223fa1820dd71e6ab0e50d4964760789209
check_cxx_symbol_exists(sasl_server_init "sys/types.h;sasl/sasl.h"
CYRUS_HARDCODED)
cmake_pop_check_state()
if(CYRUS_HARDCODED)
set(CYRUS_LDFLAGS -lsasl2)
add_library(HardcodedCyrusDep INTERFACE)
add_library(PkgConfig::CYRUS ALIAS HardcodedCyrusDep)
target_link_libraries(HardcodedCyrusDep INTERFACE sasl2)
set(CYRUS_FOUND true)
endif()
endif()
@@ -121,11 +141,21 @@ if(WANT_CYRUS)
endif()
endif()
tristate_option(ARGON "Store password hashes using Argon2id instead of SHA-256")
if(WANT_ARGON)
pkg_check_modules(ARGON ${TRISTATE_ARGON_REQUIRED} IMPORTED_TARGET libargon2)
endif()
set(ZNC_HAVE_ARGON "${ARGON_FOUND}")
tristate_option(ICU "Support character encodings")
if(WANT_ICU)
pkg_check_modules(ICU ${TRISTATE_ICU_REQUIRED} icu-uc)
pkg_check_modules(ICU ${TRISTATE_ICU_REQUIRED} IMPORTED_TARGET icu-uc)
endif()
set(HAVE_ICU "${ICU_FOUND}")
if(ICU_FOUND)
set(ZNC_CMAKE_FIND_DEPS "${ZNC_CMAKE_FIND_DEPS}\nfind_dependency_pc(ICU icu-uc)")
list(APPEND zncpubdeps PkgConfig::ICU)
endif()
set(WANT_PERL false CACHE BOOL "Support Perl modules")
set(WANT_PYTHON false CACHE BOOL "Support Python modules")
@@ -159,7 +189,7 @@ if(WANT_PYTHON AND NOT EXISTS
endif()
endif()
if(search_swig)
find_package(SWIG 3.0.0)
find_package(SWIG 4.0.1)
if(NOT SWIG_FOUND)
message(FATAL_ERROR
"Can't find SWIG, therefore Perl and Python aren't supported. "
@@ -171,8 +201,54 @@ if(WANT_PERL)
find_package(PerlLibs 5.10 REQUIRED)
endif()
if (WANT_PYTHON)
set (_MIN_PYTHON_VERSION 3.4)
find_package(Perl 5.10 REQUIRED)
pkg_check_modules(PYTHON "${WANT_PYTHON_VERSION}" REQUIRED)
# VERSION_GREATER_EQUAL is available only since 3.7
if (CMAKE_VERSION VERSION_LESS 3.12)
else()
# Even if FindPython3 is available (since CMake 3.12) we still use
# pkg-config, because FindPython has a hardcoded list of python
# versions, which may become outdated when new pythons are released,
# but when cmake in the distro is old.
#
# Why FindPython3 is useful at all? Because sometimes there is no
# python3.pc, but only python-3.5.pc and python-3.6.pc; which would
# force user to provide the version explicitly via
# WANT_PYTHON_VERSION. This is the case on Gentoo when NOT building
# via emerge.
if (WANT_PYTHON_VERSION STREQUAL "python3")
find_package(Python3 COMPONENTS Development)
else()
# We used to pass value like "python-3.5" to the variable.
if (WANT_PYTHON_VERSION MATCHES "^(python-)?(.*)$")
find_package(Python3 COMPONENTS Development
EXACT "${CMAKE_MATCH_2}")
else()
message(FATAL_ERROR "Invalid value of WANT_PYTHON_VERSION")
endif()
endif()
if (Python3_FOUND AND Python3_VERSION VERSION_LESS
${_MIN_PYTHON_VERSION})
message(STATUS
"Python too old, need at least ${_MIN_PYTHON_VERSION}")
set(Python3_FOUND OFF)
else()
# Compatibility with pkg-config variables
set(Python3_LDFLAGS "${Python3_LIBRARIES}")
endif()
endif()
if (NOT Python3_FOUND AND WANT_PYTHON_VERSION MATCHES "^python")
# Since python 3.8, -embed is required for embedding.
pkg_check_modules(Python3
"${WANT_PYTHON_VERSION}-embed >= ${_MIN_PYTHON_VERSION}")
if (NOT Python3_FOUND)
pkg_check_modules(Python3
"${WANT_PYTHON_VERSION} >= ${_MIN_PYTHON_VERSION}")
endif()
endif()
if (NOT Python3_FOUND)
message(FATAL_ERROR "Python 3 is not found. Try disabling it.")
endif()
endif()
set(WANT_TCL false CACHE BOOL "Support Tcl modules")
@@ -192,6 +268,7 @@ if(Boost_LOCALE_FOUND AND GETTEXT_MSGFMT_EXECUTABLE)
set(HAVE_I18N true)
else()
set(HAVE_I18N false)
message(STATUS "Boost.Locale or gettext (msgfmt) is not found, disabling i18n support")
endif()
if(HAVE_I18N AND GETTEXT_MSGMERGE_EXECUTABLE)
@@ -208,11 +285,41 @@ else()
set(CSOCK_USE_POLL true)
endif()
find_package(cctz QUIET)
set(cctz_cc "")
if (cctz_FOUND)
message(STATUS "Found cctz at ${cctz_DIR}")
else()
message(STATUS "Will build cctz")
set(cctz_cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/civil_time_detail.cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/time_zone_fixed.cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/time_zone_format.cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/time_zone_if.cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/time_zone_impl.cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/time_zone_info.cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/time_zone_libc.cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/time_zone_lookup.cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/time_zone_posix.cc
${PROJECT_SOURCE_DIR}/third_party/cctz/src/zone_info_source.cc
)
add_library(cctz INTERFACE)
add_library(cctz::cctz ALIAS cctz)
target_include_directories(cctz INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/third_party/cctz/include>)
if (APPLE)
find_library(CoreFoundation CoreFoundation REQUIRED)
target_link_libraries(cctz INTERFACE ${CoreFoundation})
endif()
endif()
check_cxx_symbol_exists(getopt_long "getopt.h" HAVE_GETOPT_LONG)
check_cxx_symbol_exists(lstat "sys/types.h;sys/stat.h;unistd.h" HAVE_LSTAT)
check_cxx_symbol_exists(getpassphrase "stdlib.h" HAVE_GETPASSPHRASE)
check_cxx_symbol_exists(tcsetattr "termios.h;unistd.h" HAVE_TCSETATTR)
check_cxx_symbol_exists(clock_gettime "time.h" HAVE_CLOCK_GETTIME)
check_cxx_symbol_exists(gethostname "unistd.h" ZNC_HAVE_GETHOSTNAME)
check_cxx_symbol_exists(uname "sys/utsname.h" ZNC_HAVE_UNAME)
# Note that old broken systems, such as OpenBSD, NetBSD, which don't support
# AI_ADDRCONFIG, also have thread-unsafe getaddrinfo(). Gladly, they fixed
@@ -237,12 +344,24 @@ if(append_git_version)
endif()
file(GLOB csocket_files LIST_DIRECTORIES FALSE
"${PROJECT_SOURCE_DIR}/third_party/Csocket/Csocket.*")
if(csocket_files STREQUAL "")
message(FATAL_ERROR " It looks like git submodules are not initialized.\n"
" Run: git submodule update --init --recursive")
execute_process(COMMAND git status
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE git_status_var
OUTPUT_QUIET
ERROR_QUIET)
if(git_status_var)
message(FATAL_ERROR
" It looks like git submodules are not initialized.\n"
" Either this is not a git clone, or you don't have git installed.\n"
" Fetch the tarball from the website: https://znc.in/releases/ ")
else()
message(FATAL_ERROR
" It looks like git submodules are not initialized.\n"
" Run: git submodule update --init --recursive")
endif()
endif()
install(DIRECTORY webskins
@@ -294,6 +413,8 @@ else()
endif()
configure_file("include/znc/zncconfig.h.cmake.in" "include/znc/zncconfig.h")
configure_file("test/integration/znctestconfig.h.cmake.in"
"test/integration/znctestconfig.h")
add_subdirectory(include)
add_subdirectory(src)
add_subdirectory(modules)
@@ -318,6 +439,8 @@ include(CMakePackageConfigHelpers)
write_basic_package_version_file("ZNCConfigVersion.cmake"
COMPATIBILITY AnyNewerVersion)
install(FILES
"${PROJECT_SOURCE_DIR}/cmake/CMakeFindDependencyMacroPC.cmake"
"${PROJECT_SOURCE_DIR}/cmake/use_homebrew.cmake"
"${PROJECT_BINARY_DIR}/ZNCConfig.cmake"
"${PROJECT_BINARY_DIR}/ZNCConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/znc/cmake")
@@ -344,12 +467,13 @@ summary_line("SSL " "${OPENSSL_FOUND}")
summary_line("IPv6 " "${WANT_IPV6}")
summary_line("Async DNS" "${HAVE_THREADED_DNS}")
summary_line("Perl " "${PERLLIBS_FOUND}")
summary_line("Python " "${PYTHON_FOUND}")
summary_line("Python " "${Python3_FOUND}")
summary_line("Tcl " "${TCL_FOUND}")
summary_line("Cyrus " "${CYRUS_FOUND}")
summary_line("Charset " "${ICU_FOUND}")
summary_line("Zlib " "${ZLIB_FOUND}")
summary_line("i18n " "${HAVE_I18N}")
summary_line("Argon2 " "${ZNC_HAVE_ARGON}")
include(render_framed_multiline)
render_framed_multiline("${summary_lines}")
@@ -357,8 +481,3 @@ render_framed_multiline("${summary_lines}")
message("")
message("Now you can run 'make' to compile ZNC")
message("")
# TODO
# ====
#
# remove old configure.ac and Makefile.in
+389
View File
@@ -1,3 +1,392 @@
# ZNC 1.9.1 (2024-07-03)
* This is a security release to fix CVE-2024-39844: remote code execution vulnerability in modtcl.
* To mitigate this for existing installations, simply unload the modtcl module for every user, if it's loaded. Note that only users with admin rights can load modtcl at all.
* Thanks to Johannes Kuhn (DasBrain) for reporting, to glguy for the patch, and to multiple IRC network operators for help with mitigating this on server side before disclosure.
* Improve tooltips in webadmin.
# ZNC 1.9.0 (2024-02-22)
## New
* Support for capability negotiation 302 and `cap-notify`. ZNC now has API `AddServerDependentCapability()`, using which modules can easily implement new capabilities: if server supports a cap, it will automatically be offered to clients which support `cap-notify` and ZNC will notify the module when the capability is enabled or disabled for server and for each client.
* Several capabilities (`away-notify`, `account-notify`, `extended-join`) were moved from the core to a new module: corecaps.
* The corecaps module is loaded automatically when upgrading from old config and when creating new config, but it's possible to unload it.
* Note: users who were using pre-release versions of 1.9.x (from git or from nightly tarballs) won't have it loaded automatically, because the existing config states `Version = 1.9`. In such case you can load it manually. This is to honor choice of users who decide to unload it, since we don't know whether the module is missing intentionally.
* Added support for `account-tag` capability, also in corecaps module.
* Updated password hashing algorithm from SHA-256 to Argon2id (if libargon2 is installed). Existing passwords are transparently upgraded upon login.
* Allow ordering of channels: via `ListChans`, `MoveChan` and `SwapChans` commands, and via webadmin.
* New user options: `DenySetIdent`, `DenySetNetwork`, `DenySetRealName`, `DenySetQuitMsg`, `DenySetCTCPReplies`.
* Switched `--makeconf` wizard default network from freenode to Libera.
* Added Portuguese and Turkish translations.
* znc-buildmod: output where the module was written to
## Fixes
* Fixed crash when receiving SASL lines from server without having negotiated SASL via CAP.
* Fixed build with SWIG 4.2.0.
* Fixed build with LibreSSL.
* Fixed handling of timezones when parsing server-time tags received from server.
* Use module names as the module ident, otherwise some clients were merging conversations with different modules together.
* Stopped sending invalid 333 (`RPL_TOPICWHOTIME`) to client if topic owner is unknown.
* Fixed an ODR violation.
* Better hide password in PASS debug lines, sometimes it was not hidden.
* CAP REQ sent by client without CAP LS now suspends the registration as the spec requires.
## Modules
* autoop: In some cases settings were parsed incorrectly, resulting in failure to do the autoop, now it's fixed.
* clientnotify: Added options to reduce amount of notifications depending on the IP and the client ID of the connecting client.
* controlpanel: Fixed help output.
* log: Log nickserv account in the joins lines.
* modperl: Allow overriding label for timers, which means now there can be more than 1 timer per module.
* modpython:
* Rewrote internals of how modpython loads modules.
* Main motivation for the switch from using `imp` to using `importlib` was to support Python 3.12+.
* As an additional benefit, now it's possible to structure the module as a python package (a subdirectory with `__init__.py` and other .py files).
* All the old python modules should load as they were before.
* ZNC no longer supports loading a C python extension directly through modpython (though I doubt there were any users of that obscure feature): if you want to some parts of the module to be compiled, you can always import that from `__init__.py`.
* Implemented `Module.AddCommand()`
* route_replies:
* Added Solanum-specific 337 (`RPL_WHOISTEXT`) to possible replies of `/whois`.
* Route replies to `/topic`.
* sasl: Don't forward 908 (`RPL_SASLMECHS`) to clients.
* webadmin: Fixed order of breadcrumbs in network page.
* watch: Allow new entries to use spaces.
## Notes for package maintainers
* Require C++17 compiler. That is, GCC 8+ or Clang 5+.
* Removed autoconf, leaving only CMake as the build system. The `configure` script is now merely a wrapper for CMake, and accepts mostly the same parameters as the old `configure`. You can use either `configure` as before, or CMake directly. Minimum supported CMake version is 3.13.
* If cctz library is available on the system, it will be used, otherwise the bundled copy will be used.
* libargon2 is new optional dependency.
* Dropped support for Python < 3.4
* Dropped support for SWIG < 4.0.1
* The systemd unit now passes `--datadir=/var/lib/znc`.
## Internal
* Switched to steady clock for cache map and for sockets to fix certain issues with leap seconds and DST.
* Made `CUser::Put...()` send to all clients instead of only networkless clients. Deprecate `CUser::PutAllUser()`.
* Setup Github Actions to replace old Travis CI setup.
* Added CIFuzz.
* Added CodeQL.
* List of translators is now automatically generated from Crowdin.
* Modernized the way how CMake is used.
* Updated default SSL settings from Mozilla recommendations.
* Rewrote message parsing using `std::string_view`, improving the performance of the parser.
* Web: removed legacy xhtml syntax.
* Documented more functions.
* Made some integration tests run faster by changing ServerThrottle value in the test.
# ZNC 1.8.2 (2020-07-07)
## New
* Polish translation
* List names of translators in TRANSLATORS.md file in source, as this contribution isn't directly reflected in git log
* During --makeconf warn about listening on port 6697 too, not only about 6667
## Fixes
* webadmin: When confirming deletion of a network and selecting No, redirect to the edituser page instead of listusers page
* Make more client command results translateable, which were missed before
# ZNC 1.8.1 (2020-05-07)
Fixed bug introduced in ZNC 1.8.0:
Authenticated users can trigger an application crash (with a NULL pointer dereference) if echo-message is not enabled and there is no network. CVE-2020-13775
# ZNC 1.8.0 (2020-05-01)
## New
* Output of various commands (e.g. `/znc help`) was switched from a table to a list
* Support IP while verifying SSL certificates
* Make it more visible that admins have lots of privileges
## Fixes
* Fix parsing of channel modes when the last parameter starts with a colon, improving compatibility with InspIRCd v3
* Fix null dereference on startup when reading invalid config
* Don't show server passwords on ZNC startup
* Fix build with newer OpenSSL
* Fix in-source CMake build
* Fix echo-message for `status`
## Modules
* controlpanel: Add already supported NoTrafficTimeout User variable to help output
* modpython:
* Use FindPython3 in addition to pkg-config in CMake to simplify builds on Gentoo when not using emerge
* Support python 3.9
* modtcl: Added GetNetworkName
* partyline: Module is removed
* q: Module is removed
* route_replies: Handle more numerics
* sasl: Fix sending of long authentication information
* shell: Unblock signals when spawning child processes
* simple_away: Convert to UTC time
* watch: Better support multiple clients
* webadmin: Better wording for TrustPKI setting
## Internal
* Refactor the way how SSL certificate is checked to simplify future socket-related refactors
* Build integration test and ZNC itself with the same compiler (https://bugs.gentoo.org/699258)
* Various improvements for translation CI
* Normalize variable name sUserName/sUsername
* Make de-escaping less lenient
# ZNC 1.7.5 (2019-09-23)
* modpython: Add support for Python 3.8
* modtcl: install .tcl files when building with CMake
* nickserv: report success of Clear commands
* Update translations, add Italian, Bulgarian, fix name of Dutch
* Update error messages to be clearer
* Add a deprecation warning to ./configure to use CMake instead in addition to an already existing warning in README
# ZNC 1.7.4 (2019-06-19)
## Fixes
* This is a security release to fix CVE-2019-12816 (remote code execution by existing non-admin users). Thanks to Jeriko One for the bugreport.
* Send "Connected!" messages to client to the correct nick.
# Internal
* Increase znc-buildmod timeout in the test.
# ZNC 1.7.3 (2019-03-30)
## Fixes
This is a security release to fix CVE-2019-9917. Thanks to LunarBNC for the bugreport.
## New
Docker only: the znc image now supports --user option of docker run.
# ZNC 1.7.2 (2019-01-19)
## New
* Add French translation
* Update translations
## Fixes
* Fix compilation without deprecated APIs in OpenSSL
* Distinguish Channel CTCP Requests and Replies
* admindebug: Enforce need of TTY to turn on debug mode
* controlpanel: Add missing return to ListNetMods
* webadmin: Fix adding the last allowed network
## Internal
* Add more details to DNS error logs
# ZNC 1.7.1 (2018-07-17)
## Security critical fixes
* CVE-2018-14055: non-admin user could gain admin privileges and shell access by injecting values into znc.conf.
* CVE-2018-14056: path traversal in HTTP handler via ../ in a web skin name.
## Core
* Fix znc-buildmod to not hardcode the compiler used to build ZNC anymore in CMake build
* Fix language selector. Russian and German were both not selectable.
* Fix build without SSL support
* Fix several broken strings
* Stop spamming users about debug mode. This feature was added in 1.7.0, now reverted.
## New
* Add partial Spanish, Indonesian, and Dutch translations
## Modules
* adminlog: Log the error message again (regression of 1.7.0)
* admindebug: New module, which allows admins to turn on/off --debug in runtime
* flooddetach: Fix description of commands
* modperl: Fix memory leak in NV handling
* modperl: Fix functions which return VCString
* modpython: Fix functions which return VCString
* webadmin: Fix fancy CTCP replies editor for Firefox. It was showing the plain version even when JS is enabled
## Internal
* Deprecate one of the overloads of CMessage::GetParams(), rename it to CMessage::GetParamsColon()
* Don't throw from destructor in the integration test
* Fix a warning with integration test / gmake / znc-buildmod interaction.
# ZNC 1.7.0 (2018-05-01)
## New
* Add CMake build. Minimum supported CMake version is 3.1. For now ZNC can be built with either CMake or autoconf. In future autoconf is going to be removed.
* Currently `znc-buildmod` requires python if CMake was used; if that's a concern for you, please open a bug.
* Increase minimum GCC version from 4.7 to 4.8. Minimum Clang version stays at 3.2.
* Make ZNC UI translateable to different languages (only with CMake), add partial Russian and German translations.
* If you want to translate ZNC to your language, please join https://crowdin.com/project/znc-bouncer
* Configs written before ZNC 0.206 can't be read anymore
* Implement IRCv3.2 capabilities `away-notify`, `account-notify`, `extended-join`
* Implement IRCv3.2 capabilities `echo-message`, `cap-notify` on the "client side"
* Update capability names as they are named in IRCv3.2: `znc.in/server-time-iso``server-time`, `znc.in/batch``batch`. Old names will continue working for a while, then will be removed in some future version.
* Make ZNC request `server-time` from server when available
* Increase accepted line length from 1024 to 2048 to give some space to message tags
* Separate buffer size settings for channels and queries
* Support separate `SSLKeyFile` and `SSLDHParamFile` configuration in addition to existing `SSLCertFile`
* Add "AuthOnlyViaModule" global/user setting
* Added pyeval module
* Added stripcontrols module
* Add new substitutions to ExpandString: `%empty%` and `%network%`.
* Stop defaulting real name to "Got ZNC?"
* Make the user aware that debug mode is enabled.
* Added `ClearAllBuffers` command
* Don't require CSRF token for POSTs if the request uses HTTP Basic auth.
* Set `HttpOnly` and `SameSite=strict` for session cookies
* Add SNI SSL client support
* Add support for CIDR notation in allowed hosts list and in trusted proxy list
* Add network-specific config for cert validation in addition to user-supplied fingerprints: `TrustAllCerts`, defaults to false, and `TrustPKI`, defaults to true.
* Add `/attach` command for symmetry with `/detach`. Unlike `/join` it allows wildcards.
* Timestamp format now supports sub-second precision with `%f`. Used in awaystore, listsockets, log modules and buffer playback when client doesn't support server-time
* Build on macOS using ICU, Python, and OpenSSL from Homebrew, if available
* Remove `--with-openssl=/path` option from ./configure. SSL is still supported and is still configurable
## Fixes
* Revert tables to how they were in ZNC 1.4
* Remove flawed Add/Del/ListBindHost(s). They didn't correctly do what they were intended for, but users often confused them with the SetBindHost option. SetBindHost still works.
* Fix disconnection issues when being behind NAT by decreasing the interval how often PING is sent and making it configurable via a setting to change ping timeout time
* Change default flood rates to match RFC1459, prevent excess flood problems
* Match channel names and hostmasks case-insensitively in autoattach, autocycle, autoop, autovoice, log, watch modules
* Fix crash in shell module which happens if client disconnects at a wrong time
* Decrease CPU usage when joining channels during startup or reconnect, add config write delay setting
* Always send the users name in NOTICE when logging in.
* Don't try to quit multiple times
* Don't send PART to client which sent QUIT
* Send failed logins to NOTICE instead of PRIVMSG
* Stop creating files with odd permissions on Solaris
* Save channel key on JOIN even if user was not on the channel yet
* Stop buffering and echoing CTCP requests and responses to other clients with self-message, except for /me
* Support discovery of tcl 8.6 during `./configure`
## Modules
* adminlog:
* Make path configurable
* alias:
* Add `Dump` command to copy your config between users
* awaystore:
* Add `-chans` option which records channel highlights
* blockmotd:
* Add `GetMotd` command
* clearbufferonmsg:
* Add options which events trigger clearation of buffers.
* controlpanel:
* Add the `DelServer` command.
* Add `$user` and `$network` aliases for `$me` and `$net` respectively
* Allow reseting channel-specific `AutoClearChanBuffer` and `BufferSize` settings by setting them to `-`
* Change type of values from "double" to "number", which is more obvious for non-programmers
* crypt:
* Fix build with LibreSSL
* Cover notices, actions and topics
* Don't use the same or overlapping NickPrefix as StatusPrefix
* Add DH1080 key exchange
* Add Get/SetNickPrefix commands, hide the internal keyword from ListKeys
* cyrusauth:
* Improve UI
* fail2ban:
* Make timeout and attempts configurable, add BAN, UNBAN and LIST commands
* flooddetach:
* Detach on nick floods
* keepnick:
* Improve behaviour by listening to ircd-side numeric errors
* log:
* Add `-timestamp` option
* Add options to hide joins, quits and nick changes.
* Stop forcing username and network name to be lower case in filenames
* Log user quit messages
* missingmotd:
* Include nick in IRC numeric 422 command, reduce client confusion
* modperl:
* Provide `operator ""` for `ZNC::String`
* Honor `PERL5LIB` env var
* Fix functions like `HasPerm()` which accept `char`
* When a broken module couldn't be loaded, it couldn't be loaded anymore even if it was fixed later.
* Force strings to UTF-8 in modperl to fix double encoding during concatenation/interpolation.
* modpython:
* Require ZNC to be built with encodings support
* Disable legacy encoding mode when modpython is loaded.
* Support `CQuery` and `CServer`
* nickserv:
* Use `/nickserv identify` by default instead of `/msg nickserv`.
* Support messages from X3 services
* notify_connect:
* Show client identification
* sasl:
* Add web interface
* Enable all known mechanisms by default
* Make the first requirement for SET actually mandatory, return information about settings if no input for SET
* schat:
* Require explicit path to certificate.
* simple_away:
* Use ExpandString for away reason, rename old `%s` to `%awaytime%`
* Add `MinClients` option
* stickychan:
* Save registry on every stick/unstick action, auto-save if channel key changes
* Stop checking so often, increase delay to once every 3 minutes
* webadmin:
* Make server editor and CTCP replies editor more fancy, when JS is enabled
* Make tables sortable.
* Allow reseting chan buffer size by entering an empty value
* Show per-network traffic info
* Make the traffic info page visible for non-admins, non-admins can see only their traffic
## Internal
* Stop pretending that ZNC ABI is stable, when it's not. Make module version checks more strict and prevent crashes when loading a module which are built for the wrong ZNC version.
* Add an integration test
* Various HTML changes
* Introduce a CMessage class and its subclasses
* Add module callbacks which accept CMessage, deprecate old callbacks
* Add `OnNumericMessage` module callback, which previously was possible only with `OnRaw`, which could give unexpected results if the message has IRCv3.2 tags.
* Modernize code to use more C++11 features
* Various code cleanups
* Fix CSS of `_default_` skin for Fingerprints section
* Add `OnUserQuitMessage()` module hook.
* Add `OnPrivBufferStarting()` and `OnPrivBufferEnding()` hooks
* `CString::WildCmp()`: add an optional case-sensitivity argument
* Do not call `OnAddUser()` hook during ZNC startup
* Allow modules to override CSRF protection.
* Rehash now reloads only global settings
* Remove `CAP CLEAR`
* Add `CChan::GetNetwork()`
* `CUser`: add API for removing and clearing allowed hosts
* `CZNC`: add missing SSL-related getters and setters
* Add a possibility (not an "option") to disable launch after --makeconf
* Move Unix signal processing to a dedicated thread.
* Add clang-format configuration, switch tabs to spaces.
* `CString::StripControls()`: Strip background colors when we reset foreground
* Make chan modes and permissions to be char instead of unsigned char.
## Cosmetic
* Alphabetically sort the modules we compile using autoconf/Makefile
* Alphabetically sort output of `znc --help`
* Change output during startup to be more compact
* Show new server name when reconnecting to a different server with `/znc jump`
* Hide passwords in listservers output
* Filter out ZNC passwords in output of `znc -D`
* Switch znc.in URLs to https
# ZNC 1.6.6 (2018-03-05)
* Fix use-after-free in `znc --makepem`. It was broken for a long time, but
started segfaulting only now. This is a useability fix, not a security fix,
because self-signed (or signed by a CA) certificates can be created
without using `--makepem`, and then combined into znc.pem.
* Fix build on Cygwin.
# ZNC 1.6.5 (2017-03-12)
## Fixes
+53
View File
@@ -0,0 +1,53 @@
FROM alpine:3.19
ARG VERSION_EXTRA=""
ARG CMAKEFLAGS="-DVERSION_EXTRA=${VERSION_EXTRA} -DCMAKE_INSTALL_PREFIX=/opt/znc -DWANT_CYRUS=YES -DWANT_PERL=YES -DWANT_PYTHON=YES -DWANT_ARGON=YES"
ARG MAKEFLAGS=""
LABEL org.label-schema.schema-version="1.0"
LABEL org.label-schema.vcs-url="https://github.com/znc/znc"
LABEL org.label-schema.url="https://znc.in"
COPY . /znc-src
RUN set -x \
&& adduser -S znc \
&& addgroup -S znc
RUN apk add --no-cache \
argon2-libs \
boost \
build-base \
ca-certificates \
cmake \
cyrus-sasl \
gettext \
icu-dev \
icu-data-full \
openssl-dev \
perl \
python3 \
su-exec \
tini \
tzdata
RUN apk add --no-cache --virtual build-dependencies \
argon2-dev \
boost-dev \
cyrus-sasl-dev \
perl-dev \
python3-dev \
swig \
&& cd /znc-src \
&& mkdir build && cd build \
&& cmake .. ${CMAKEFLAGS} \
&& make $MAKEFLAGS \
&& make install \
&& apk del build-dependencies \
&& cd / && rm -rf /znc-src
COPY docker/slim/entrypoint.sh /
COPY docker/*/??-*.sh docker/*/startup-sequence/??-*.sh /startup-sequence/
VOLUME /znc-data
ENTRYPOINT ["/entrypoint.sh"]
Vendored
+5 -2
View File
@@ -2,7 +2,10 @@
timestamps {
node('freebsd') {
// freebsd 10.3 + pkg install git openjdk cmake icu pkgconf swig30 python3 boost-libs gettext-tools qt5-buildtools qt5-network qt5-qmake
// AWS EC2 AMI: FreeBSD 14.1-STABLE-amd64-20241003 UEFI-PREFERRED base UFS
// pkg install git openjdk22 cmake icu pkgconf swig python3 boost-libs gettext-tools qt6-base libargon2
// Then fill known_hosts with https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
// (needed for crowdin cron job in jenkins)
timeout(time: 30, unit: 'MINUTES') {
def wsdir = pwd()
stage('Checkout') {
@@ -12,7 +15,7 @@ timestamps {
}
dir("$wsdir/build") {
stage('Build') {
sh "cmake $wsdir -DWANT_PERL=ON -DWANT_PYTHON=ON -DCMAKE_INSTALL_PREFIX=$wsdir/build/install-prefix"
sh "cmake $wsdir -DWANT_PERL=ON -DWANT_PYTHON=ON -DWANT_ARGON=ON -DCMAKE_INSTALL_PREFIX=$wsdir/build/install-prefix"
sh 'make VERBOSE=1 all'
}
stage('Unit test') {
-263
View File
@@ -1,263 +0,0 @@
SHELL := @SHELL@
# Support out-of-tree builds
srcdir := @srcdir@
VPATH := @srcdir@
prefix := @prefix@
exec_prefix := @exec_prefix@
datarootdir := @datarootdir@
bindir := @bindir@
datadir := @datadir@
sysconfdir := @sysconfdir@
libdir := @libdir@
includedir := @includedir@
sbindir := @sbindir@
localstatedir := @localstatedir@
systemdsystemunitdir := @systemdsystemunitdir@
CXX := @CXX@
CXXFLAGS := -I$(srcdir)/include -Iinclude @CPPFLAGS@ @CXXFLAGS@
LDFLAGS := @LDFLAGS@
LIBS := @LIBS@
LIBZNC := @LIBZNC@
LIBZNCDIR:= @LIBZNCDIR@
MODDIR := @MODDIR@
DATADIR := @DATADIR@
PKGCONFIGDIR := $(libdir)/pkgconfig
INSTALL := @INSTALL@
INSTALL_PROGRAM := @INSTALL_PROGRAM@
INSTALL_SCRIPT := @INSTALL_SCRIPT@
INSTALL_DATA := @INSTALL_DATA@
GIT := @GIT@
SED := @SED@
GTEST_DIR := @GTEST_DIR@
GMOCK_DIR := @GMOCK_DIR@
ifeq "$(GTEST_DIR)" ""
GTEST_DIR := $(srcdir)/third_party/googletest/googletest
endif
ifeq "$(GMOCK_DIR)" ""
GMOCK_DIR := $(srcdir)/third_party/googletest/googlemock
endif
qt_CFLAGS := @qt_CFLAGS@ -fPIC -std=c++11 -pthread
qt_LIBS := @qt_LIBS@ -pthread
# Force the simple internal regex engine to get consistent behavior on all platforms.
# See https://code.google.com/p/chromium/issues/detail?id=317224 for more details.
GTEST_FLAGS := -DGTEST_HAS_POSIX_RE=0 -I$(GMOCK_DIR)/include -I$(GTEST_DIR)/include
# Silence warnings about overload virtual Csock::Write(), and missing field
# initializers in both gtest and gmock
GTEST_FLAGS += -Wno-overloaded-virtual -Wno-missing-field-initializers
LIB_SRCS := ZNCString.cpp Csocket.cpp znc.cpp IRCNetwork.cpp User.cpp IRCSock.cpp \
Client.cpp Chan.cpp Nick.cpp Server.cpp Modules.cpp MD5.cpp Buffer.cpp Utils.cpp \
FileUtils.cpp HTTPSock.cpp Template.cpp ClientCommand.cpp Socket.cpp SHA256.cpp \
WebModules.cpp Listener.cpp Config.cpp ZNCDebug.cpp Threads.cpp version.cpp Query.cpp \
SSLVerifyHost.cpp Message.cpp Translation.cpp
LIB_SRCS := $(addprefix src/,$(LIB_SRCS))
BIN_SRCS := src/main.cpp
LIB_OBJS := $(patsubst %cpp,%o,$(LIB_SRCS))
BIN_OBJS := $(patsubst %cpp,%o,$(BIN_SRCS))
TESTS := StringTest ConfigTest UtilsTest ThreadTest NickTest ClientTest NetworkTest \
MessageTest ModulesTest IRCSockTest QueryTest BufferTest UserTest
TESTS := $(addprefix test/,$(addsuffix .o,$(TESTS)))
CLEAN := znc src/*.o test/*.o core core.* .version_extra .depend modules/.depend \
unittest $(LIBZNC)
DISTCLEAN := Makefile config.log config.status znc-buildmod include/znc/zncconfig.h \
modules/Makefile man/Makefile znc.pc znc-uninstalled.pc test/Makefile
CXXFLAGS += -D_MODDIR_=\"$(MODDIR)\" -D_DATADIR_=\"$(DATADIR)\"
ifneq "$(V)" ""
VERBOSE=1
endif
ifeq "$(VERBOSE)" ""
Q=@
E=@echo
C=-s
else
Q=
E=@\#
C=
endif
.PHONY: all man modules clean distclean install version_extra_recompile test
.SECONDARY:
all: znc man modules $(LIBZNC)
@echo ""
@echo " ZNC was successfully compiled."
@echo " Use '$(MAKE) install' to install ZNC to '$(prefix)'."
ifeq "$(LIBZNC)" ""
OBJS := $(BIN_OBJS) $(LIB_OBJS)
znc: $(OBJS)
$(E) Linking znc...
$(Q)$(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
else
znc: $(BIN_OBJS) $(LIBZNC)
$(E) Linking znc...
$(Q)$(CXX) $(LDFLAGS) -o $@ $(BIN_OBJS) -L. -lznc -Wl,-rpath,$(LIBZNCDIR) $(LIBS)
$(LIBZNC): $(LIB_OBJS)
$(E) Linking $(LIBZNC)...
$(Q)$(CXX) $(LDFLAGS) -shared -o $@ $(LIB_OBJS) $(LIBS) -Wl,--out-implib=libznc.dll.a
endif
unittest: $(LIB_OBJS) test/gtest-all.o test/gmock-all.o test/gmock-main.o $(TESTS)
$(E) Linking unit test...
$(Q)$(CXX) $(LDFLAGS) -o $@ $(LIB_OBJS) test/gtest-all.o test/gmock-all.o test/gmock-main.o $(TESTS) $(LIBS)
inttest: test/Integration.o test/Int-gtest-all.o test/Int-gmock-all.o test/Int-gmock-main.o
$(E) Linking integration test...
$(Q)g++ -std=c++11 -o $@ test/Integration.o test/Int-gtest-all.o test/Int-gmock-all.o test/Int-gmock-main.o $(LIBS) $(qt_LIBS)
man:
@$(MAKE) -C man $(C)
modules: $(LIBZNC) include/znc/Csocket.h
@$(MAKE) -C modules $(C)
clean:
rm -rf $(CLEAN)
@$(MAKE) -C modules clean;
@$(MAKE) -C man clean
distclean: clean
rm -rf $(DISTCLEAN)
src/%.o: src/%.cpp Makefile include/znc/Csocket.h
@mkdir -p .depend src
$(E) Building core object $*...
$(Q)$(CXX) $(CXXFLAGS) -c -o $@ $< -MD -MF .depend/$*.dep -MT $@
test/%.o: test/%.cpp Makefile include/znc/Csocket.h
@mkdir -p .depend test
$(E) Building test object $*...
$(Q)$(CXX) $(CXXFLAGS) $(GTEST_FLAGS) -c -o $@ $< -MD -MF .depend/$*.test.dep -MT $@
test/gtest-all.o: $(GTEST_DIR)/src/gtest-all.cc Makefile
@mkdir -p .depend test
$(E) Building test object gtest-all...
$(Q)$(CXX) $(CXXFLAGS) $(GTEST_FLAGS) -I$(GTEST_DIR) -c -o $@ $< -MD -MF .depend/gtest-all.dep -MT $@
test/gmock-all.o: $(GMOCK_DIR)/src/gmock-all.cc Makefile
@mkdir -p .depend test
$(E) Building test object gmock-all...
$(Q)$(CXX) $(CXXFLAGS) $(GTEST_FLAGS) -I$(GMOCK_DIR) -c -o $@ $< -MD -MF .depend/gmock-all.dep -MT $@
test/gmock-main.o: $(GMOCK_DIR)/src/gmock_main.cc Makefile
@mkdir -p .depend test
$(E) Building test object gmock-main...
$(Q)$(CXX) $(CXXFLAGS) $(GTEST_FLAGS) -c -o $@ $< -MD -MF .depend/gmock-main.dep -MT $@
# Qt fails under TSAN, so CXXFLAGS/LDFLAGS can't be used.
test/Integration.o: test/integration/main.cpp Makefile
@mkdir -p .depend test
$(E) Building test object Integration...
$(Q)g++ $(qt_CFLAGS) $(GTEST_FLAGS) -c -o $@ $< -MD -MF .depend/Integration.test.dep -MT $@ '-DZNC_BIN_DIR="$(bindir)"' '-DZNC_SRC_DIR="$(realpath $(srcdir))"'
test/Int-gtest-all.o: $(GTEST_DIR)/src/gtest-all.cc Makefile
@mkdir -p .depend test
$(E) Building test object Int-gtest-all...
$(Q)g++ $(qt_CFLAGS) $(GTEST_FLAGS) -I$(GTEST_DIR) -c -o $@ $< -MD -MF .depend/Int-gtest-all.dep -MT $@
test/Int-gmock-all.o: $(GMOCK_DIR)/src/gmock-all.cc Makefile
@mkdir -p .depend test
$(E) Building test object Int-gmock-all...
$(Q)g++ $(qt_CFLAGS) $(GTEST_FLAGS) -I$(GMOCK_DIR) -c -o $@ $< -MD -MF .depend/Int-gmock-all.dep -MT $@
test/Int-gmock-main.o: $(GMOCK_DIR)/src/gmock_main.cc Makefile
@mkdir -p .depend test
$(E) Building test object Int-gmock-main...
$(Q)g++ $(qt_CFLAGS) $(GTEST_FLAGS) -c -o $@ $< -MD -MF .depend/Int-gmock-main.dep -MT $@
ifneq "THIS_IS_NOT_TARBALL" ""
# If git commit was changed since previous build, add a phony target to dependencies, forcing version.o to be recompiled
# Nightlies have pregenerated version.cpp
src/version.cpp: Makefile version.sh $(shell if [ x`cat .version_extra 2> /dev/null` != x`$(srcdir)/version.sh "$(GIT)" 3>&2 2> /dev/null` ]; then echo version_extra_recompile; fi)
@mkdir -p .depend src
$(E) Building source file version.cpp...
$(Q)WRITE_OUTPUT=yes $(srcdir)/version.sh "$(GIT)" > .version_extra 2> /dev/null
CLEAN += src/version.cpp
endif
CLEAN += src/Csocket.cpp include/znc/Csocket.h
src/Csocket.cpp: third_party/Csocket/Csocket.cc
@rm -f $@
@mkdir -p src
@sed -e 's:#include "Csocket.h":#include <znc/Csocket.h>:' $^ > $@
include/znc/Csocket.h: third_party/Csocket/Csocket.h
@rm -f $@
@mkdir -p include/znc
@sed -e 's:#include "defines.h":#include <znc/defines.h>:' $^ > $@
third_party/Csocket/Csocket.h third_party/Csocket/Csocket.cc:
@echo It looks like git submodules are not initialized. Run: git submodule update --init --recursive
@exit 1
znc.service: znc.service.in
@sed -e "s:\@CMAKE_INSTALL_FULL_BINDIR\@:$(bindir):" $^ > $@
CLEAN += znc.service
install: znc znc.service $(LIBZNC)
test -d $(DESTDIR)$(bindir) || $(INSTALL) -d $(DESTDIR)$(bindir)
test -d $(DESTDIR)$(includedir)/znc || $(INSTALL) -d $(DESTDIR)$(includedir)/znc
test -d $(DESTDIR)$(PKGCONFIGDIR) || $(INSTALL) -d $(DESTDIR)$(PKGCONFIGDIR)
test -d $(DESTDIR)$(MODDIR) || $(INSTALL) -d $(DESTDIR)$(MODDIR)
test -d $(DESTDIR)$(DATADIR) || $(INSTALL) -d $(DESTDIR)$(DATADIR)
cp -R $(srcdir)/webskins $(DESTDIR)$(DATADIR)
find $(DESTDIR)$(DATADIR)/webskins -type d -exec chmod 0755 '{}' \;
find $(DESTDIR)$(DATADIR)/webskins -type f -exec chmod 0644 '{}' \;
$(INSTALL_PROGRAM) znc $(DESTDIR)$(bindir)
$(INSTALL_SCRIPT) znc-buildmod $(DESTDIR)$(bindir)
$(INSTALL_DATA) $(srcdir)/include/znc/*.h $(DESTDIR)$(includedir)/znc
$(INSTALL_DATA) include/znc/*.h $(DESTDIR)$(includedir)/znc
$(INSTALL_DATA) znc.pc $(DESTDIR)$(PKGCONFIGDIR)
@$(MAKE) -C modules install DESTDIR=$(DESTDIR);
if test -n "$(LIBZNC)"; then \
test -d $(DESTDIR)$(LIBZNCDIR) || $(INSTALL) -d $(DESTDIR)$(LIBZNCDIR) || exit 1 ; \
$(INSTALL_PROGRAM) $(LIBZNC) $(DESTDIR)$(LIBZNCDIR) || exit 1 ; \
$(INSTALL_PROGRAM) libznc.dll.a $(DESTDIR)$(libdir) || exit 1 ; \
fi
@$(MAKE) -C man install DESTDIR=$(DESTDIR)
@HAVE_SYSTEMD_TRUE@test -d $(DESTDIR)$(systemdsystemunitdir) || $(INSTALL) -d $(DESTDIR)$(systemdsystemunitdir)
@HAVE_SYSTEMD_TRUE@$(INSTALL_DATA) $(srcdir)/znc.service $(DESTDIR)$(systemdsystemunitdir)
@echo ""
@echo "******************************************************************"
@echo " ZNC was successfully installed."
@echo " You can use '$(bindir)/znc --makeconf'"
@echo " to generate a config file."
@echo ""
@echo " If you need help with using ZNC, please visit our wiki at:"
@echo " https://znc.in"
uninstall:
rm $(DESTDIR)$(bindir)/znc
rm $(DESTDIR)$(bindir)/znc-buildmod
rm $(DESTDIR)$(includedir)/znc/*.h
rm $(DESTDIR)$(PKGCONFIGDIR)/znc.pc
rm -rf $(DESTDIR)$(DATADIR)/webskins
if test -n "$(LIBZNC)"; then \
rm $(DESTDIR)$(LIBZNCDIR)/$(LIBZNC) || exit 1 ; \
rmdir $(DESTDIR)$(LIBZNCDIR) || exit 1 ; \
fi
@$(MAKE) -C man uninstall DESTDIR=$(DESTDIR)
@if test -n "modules"; then \
$(MAKE) -C modules uninstall DESTDIR=$(DESTDIR); \
fi
rmdir $(DESTDIR)$(bindir)
rmdir $(DESTDIR)$(includedir)/znc
rmdir $(DESTDIR)$(PKGCONFIGDIR)
@echo "Successfully uninstalled, but empty directories were left behind"
test: unittest
$(Q)./unittest
# This test uses files at <prefix>/lib/znc, which is less than ideal, especially from build scripts of distros.
# That's why it's a separate make target.
test2: inttest
$(Q)./inttest
-include $(wildcard .depend/*.dep)
+1
View File
@@ -16,6 +16,7 @@ ZNC includes code from jQuery UI (http://jqueryui.com/), licensed under the MIT
ZNC includes code from Selectize (http://brianreavis.github.io/selectize.js/), licensed under the Apache License 2.0.
ZNC includes modified code from CMakeFindFrameworks.cmake by Kitware, Inc., licensed under BSD License.
ZNC includes modified code from TestLargeFiles.cmake, licensed under Boost Software License, Version 1.0.
ZNC includes code from cctz (https://github.com/google/cctz), licensed under the Apache License 2.0.
ZNC is developed by these people:
+23 -38
View File
@@ -1,11 +1,9 @@
# [![ZNC](https://wiki.znc.in/resources/assets/wiki.png)](https://znc.in) - An advanced IRC bouncer
# [![ZNC](logo.png)](https://znc.in) - An advanced IRC bouncer
[![Travis Build Status](https://img.shields.io/travis/znc/znc/master.svg?label=linux%2Fmacos)](https://travis-ci.org/znc/znc)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/znc/znc/build.yml?branch=master&label=linux)](https://github.com/znc/znc/actions/workflows/build.yml)
[![Jenkins Build Status](https://img.shields.io/jenkins/s/https/jenkins.znc.in/job/znc/job/znc/job/master.svg?label=freebsd)](https://jenkins.znc.in/job/znc/job/znc/job/master/)
[![AppVeyor Build status](https://img.shields.io/appveyor/ci/DarthGandalf/znc/master.svg?label=windows)](https://ci.appveyor.com/project/DarthGandalf/znc/branch/master)
[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=1759)](https://www.bountysource.com/trackers/1759-znc?utm_source=1759&utm_medium=shield&utm_campaign=TRACKER_BADGE)
[![Coverage Status](https://img.shields.io/codecov/c/github/znc/znc.svg)](https://codecov.io/gh/znc/znc)
[![Coverity Scan Build Status](https://img.shields.io/coverity/scan/6778.svg)](https://scan.coverity.com/projects/znc-coverity)
## Table of contents
@@ -26,10 +24,8 @@ Core:
* GNU make
* pkg-config
* GCC 4.7 or clang 3.2
* Either of:
* autoconf and automake (but only if building from git, not from tarball)
* CMake
* GCC 8 or clang 5
* CMake 3.13
## Optional Requirements
@@ -43,8 +39,8 @@ modperl:
* SWIG if building from git
modpython:
* python and its bundled libpython
* perl is required
* python 3.4+ and its bundled libpython
* perl is a build dependency
* macOS: Python from Homebrew is preferred over system version
* SWIG if building from git
@@ -54,47 +50,37 @@ cyrusauth:
Character Encodings:
* To get proper character encoding and charsets install ICU (`libicu4-dev`)
I18N (UI translation):
* Boost.Locale
* gettext is a build dependency
Argon2 password hash:
* libargon2
## Installing ZNC
Currently there are 2 build systems in place: CMake and `./configure`.
`./configure` will eventually be removed.
There is also `configure.sh` which should make migration to CMake easier:
it accepts the same parameters as `./configure`,
but calls CMake with CMake-style parameters.
### Installing with CMake
Installation from source code is performed using the CMake toolchain.
```shell
cmake .
mkdir build
cd build
cmake ..
make
make install
```
You can use `cmake-gui` or `ccmake` for more interactiveness.
There is also `configure.sh` which should make migration to CMake easier:
it accepts the same parameters as old `./configure`,
but calls CMake with CMake-style parameters.
Note for FreeBSD users:
By default base OpenSSL is selected.
If you want the one from ports, use `-DOPENSSL_ROOT_DIR=/usr/local`.
For troubleshooting, `cmake --system-information` will show you details.
### Installing with `./configure`
Installation from source code is performed using the `automake` toolchain.
If you are building from git, you will need to run `./autogen.sh` first to
produce the `configure` script.
```shell
./configure
make
make install
```
You can use `./configure --help` if you want to get a list of options, though
the defaults should be suiting most needs.
## Setting up znc.conf
For setting up a configuration file in `~/.znc` you can simply do
@@ -152,7 +138,7 @@ These directories are also in there:
- moddata - Global modules save their settings here.
(e.g. webadmin saves the current skin name in here)
- users - This is per-user data and mainly contains just a moddata
directory.
directory and a directory for each network configured.
## ZNC's config file
@@ -188,9 +174,8 @@ Python modules are loaded through the global module
## Further information
Please visit https://znc.in/ or #znc on freenode if you still have questions:
- [freenode webchat](https://webchat.freenode.net/?nick=znc_....&channels=znc)
- [ircs://irc.freenode.net:6697/znc](ircs://irc.freenode.net:6697/znc)
Please visit https://znc.in/ or #znc on Libera.Chat if you still have questions:
- [ircs://irc.libera.chat:6697/#znc](ircs://irc.libera.chat:6697/#znc)
You can get the latest development version with git:
`git clone https://github.com/znc/znc.git --recursive`
+52
View File
@@ -0,0 +1,52 @@
These people helped translating ZNC to various languages:
* Alcahest ([X] Alcahest)
* Altay
* aycanuAydemir
* bashgeek (Daniel)
* CaPaCuL
* casmo (Casper)
* ChaosEngine (Andrzej Pauli)
* cirinho (Ciro Moniz)
* CJSStryker
* Danit
* DarthGandalf
* dgw
* Dreiundachzig
* Dremski
* eggoez (Baguz Ach)
* eleanorsilly (ellie is not coding in the slightest)
* freonesuka (Андрей Вальтер)
* gremax
* hypech
* JakaMedia (Jaka Media Teknologi)
* Jay2k1
* kloun (Victor Kukshiev)
* kumanoff
* leon-th (Leon T.)
* LiteHell
* lorenzosu
* M0onshadow (Maelan)
* MikkelDK
* mkgeeky (mkgeeky)
* moonlightzzz (moonlightz)
* natinaum (natinaum)
* PauloHeaven (Paul)
* peterstanke (MAGIC)
* psychon
* remhaze
* shillos5 (Nicholas Kyriakides)
* simos (filippo.cortigiani)
* sukien
* SunOS
* tojestzart (tojestzart)
* Un1matr1x (Falk Seidel)
* unavailable (style)
* Vimart
* Wollino
* Xaris_ (Xaris)
* xAtlas (Atlas)
* Xinayder (Alexandre Oliveira)
* Zarthus (Jos Ahrens)
Generated from https://crowdin.com/project/znc-bouncer
+10 -8
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,7 +14,13 @@
# limitations under the License.
#
include("${CMAKE_CURRENT_LIST_DIR}/znc.cmake")
include(CMakeFindDependencyMacro)
include("${CMAKE_CURRENT_LIST_DIR}/CMakeFindDependencyMacroPC.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/use_homebrew.cmake")
@ZNC_CMAKE_FIND_DEPS@
include("${CMAKE_CURRENT_LIST_DIR}/znc_internal.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/znc_public.cmake")
include(CMakeParseArguments)
# For some reason cygwin fails to build modules if Threads::Threads
@@ -36,16 +42,12 @@ endif()
function(znc_setup_module)
cmake_parse_arguments(znc_mod "" "TARGET;NAME" "" ${ARGN})
set_target_properties("${znc_mod_TARGET}" PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED true
OUTPUT_NAME "${znc_mod_NAME}"
PREFIX ""
SUFFIX ".so"
NO_SONAME true
CXX_VISIBILITY_PRESET "hidden"
COMPILE_DEFINITIONS "znc_export_lib_EXPORTS")
set(znc_link "@znc_link@")
target_link_libraries("${znc_mod_TARGET}" PUBLIC "znc_internal_${znc_link}")
CXX_VISIBILITY_PRESET "hidden")
target_link_libraries("${znc_mod_TARGET}" PRIVATE ZNC::ZNC)
endfunction()
message(STATUS "Found ZNC @ZNC_VERSION@")
-44
View File
@@ -1,44 +0,0 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
# This is based on various examples which can be found everywhere.
set -e
FLAGS=${FLAGS--Wall}
ACLOCAL=${ACLOCAL-aclocal}
AUTOHEADER=${AUTOHEADER-autoheader}
AUTOCONF=${AUTOCONF-autoconf}
AUTOMAKE=${AUTOMAKE-automake}
ACLOCAL_FLAGS="${ACLOCAL_FLAGS--I m4} ${FLAGS}"
AUTOHEADER_FLAGS="${AUTOHEADER_FLAGS} ${FLAGS}"
AUTOCONF_FLAGS="${AUTOCONF_FLAGS} ${FLAGS}"
AUTOMAKE_FLAGS="${AUTOMAKE_FLAGS---add-missing} ${FLAGS}"
die() {
echo "$@"
exit 1
}
do_cmd() {
echo "Running '$@'"
$@
}
test -f configure.ac || die "No configure.ac found."
which pkg-config > /dev/null || die "ERROR: pkg-config not found. Install pkg-config and run $0 again"
# Generate aclocal.m4 for use by autoconf
do_cmd $ACLOCAL $ACLOCAL_FLAGS
# Generate zncconfig.h.in for configure
do_cmd $AUTOHEADER $AUTOHEADER_FLAGS
# Generate configure
do_cmd $AUTOCONF $AUTOCONF_FLAGS
# Copy config.sub, config.guess, install.sh, ...
# This will complain that we don't use automake, let's just ignore that
do_cmd $AUTOMAKE $AUTOMAKE_FLAGS || true
test -f config.guess -a -f config.sub -a -f install-sh ||
die "Automake didn't install config.guess, config.sub and install-sh!"
echo "(Yes, automake is supposed to fail, ignore that)"
echo
echo "You may now run ./configure."
-1
View File
@@ -1 +0,0 @@
autogen.sh
+101
View File
@@ -0,0 +1,101 @@
# This is directly based on CMake's CMakeFindDependencyMacro from 3.26.5, the only change is that it uses pkg_check_modules instead of find_package
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
CMakeFindDependencyMacro
------------------------
.. command:: find_dependency
The ``find_dependency()`` macro wraps a :command:`find_package` call for
a package dependency::
find_dependency(<dep> [...])
It is designed to be used in a
:ref:`Package Configuration File <Config File Packages>`
(``<PackageName>Config.cmake``). ``find_dependency`` forwards the correct
parameters for ``QUIET`` and ``REQUIRED`` which were passed to
the original :command:`find_package` call. Any additional arguments
specified are forwarded to :command:`find_package`.
If the dependency could not be found it sets an informative diagnostic
message and calls :command:`return` to end processing of the calling
package configuration file and return to the :command:`find_package`
command that loaded it.
.. note::
The call to :command:`return` makes this macro unsuitable to call
from :ref:`Find Modules`.
Package Dependency Search Optimizations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If ``find_dependency`` is called with arguments identical to a previous
call in the same directory, perhaps due to diamond-shaped package
dependencies, the underlying call to :command:`find_package` is optimized
out. This optimization is important to support large package dependency
graphs while avoiding a combinatorial explosion of repeated searches.
However, the heuristic cannot account for ambient variables that
affect package behavior, such as ``<PackageName>_USE_STATIC_LIBS``,
offered by some packages. Therefore package configuration files should
avoid setting such variables before their calls to ``find_dependency``.
.. versionchanged:: 3.15
Previously, the underlying call to :command:`find_package` was always
optimized out if the package had already been found. CMake 3.15
removed the optimization to support cases in which ``find_dependency``
call arguments request different components.
.. versionchanged:: 3.26
The pre-3.15 optimization was restored, but with the above-described
heuristic to account for varying ``find_dependency`` call arguments.
#]=======================================================================]
macro(find_dependency_pc dep)
find_dependency(PkgConfig)
string(SHA256 cmake_fd_call_hash "${dep};${ARGN};${${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED}")
if(_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND)
unset(cmake_fd_call_hash)
else()
list(APPEND _CMAKE_${dep}_HASH_STACK ${cmake_fd_call_hash})
set(cmake_fd_quiet_arg)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
set(cmake_fd_quiet_arg QUIET)
endif()
set(cmake_fd_required_arg)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED)
set(cmake_fd_required_arg REQUIRED)
endif()
get_property(cmake_fd_alreadyTransitive GLOBAL PROPERTY
_CMAKE_${dep}_TRANSITIVE_DEPENDENCY
)
pkg_check_modules(${dep}
${cmake_fd_quiet_arg}
${cmake_fd_required_arg}
IMPORTED_TARGET ${ARGN}
)
list(POP_BACK _CMAKE_${dep}_HASH_STACK cmake_fd_call_hash)
set("_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND" "${${dep}_FOUND}")
if(NOT DEFINED cmake_fd_alreadyTransitive OR cmake_fd_alreadyTransitive)
set_property(GLOBAL PROPERTY _CMAKE_${dep}_TRANSITIVE_DEPENDENCY TRUE)
endif()
unset(cmake_fd_alreadyTransitive)
unset(cmake_fd_call_hash)
unset(cmake_fd_quiet_arg)
unset(cmake_fd_required_arg)
if (NOT ${dep}_FOUND)
set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency ${dep} could not be found.")
set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False)
return()
endif()
endif()
endmacro()
+1 -1
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+15 -15
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,26 +14,26 @@
# limitations under the License.
#
if(NOT DEFINED cxx11check)
message(STATUS "Checking for C++11 support")
get_filename_component(_CXX11Check_dir "${CMAKE_CURRENT_LIST_FILE}"
if(NOT DEFINED cxx17check)
message(STATUS "Checking for C++17 support")
get_filename_component(_CXX17Check_dir "${CMAKE_CURRENT_LIST_FILE}"
DIRECTORY)
try_compile(cxx11_supported
"${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cxx11check"
"${_CXX11Check_dir}/cxx11check" cxx11check
OUTPUT_VARIABLE _CXX11Check_tryout)
if(cxx11_supported)
message(STATUS "Checking for C++11 support - supported")
SET(cxx11check 1 CACHE INTERNAL "C++11 support")
try_compile(cxx17_supported
"${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cxx17check"
"${_CXX17Check_dir}/cxx17check" cxx17check
OUTPUT_VARIABLE _CXX17Check_tryout)
if(cxx17_supported)
message(STATUS "Checking for C++17 support - supported")
SET(cxx17check 1 CACHE INTERNAL "C++17 support")
file(APPEND
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log"
"Output of C++11 check:\n${_CXX11Check_tryout}\n")
"Output of C++17 check:\n${_CXX17Check_tryout}\n")
else()
file(APPEND
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"Error in C++11 check:\n${_CXX11Check_tryout}\n")
message(STATUS "Checking for C++11 support - not supported")
"Error in C++17 check:\n${_CXX17Check_tryout}\n")
message(STATUS "Checking for C++17 support - not supported")
message(FATAL_ERROR " Upgrade your compiler.\n"
" GCC 4.7+ and Clang 3.2+ are known to work.")
" GCC 8+ and Clang 5+ should work.")
endif()
endif()
+1 -1
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,10 +14,10 @@
# limitations under the License.
#
cmake_minimum_required(VERSION 3.0)
project(cxx11check)
cmake_minimum_required(VERSION 3.13)
project(cxx11check LANGUAGES CXX)
set(CMAKE_VERBOSE_MAKEFILE true)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED true)
add_executable(main main.cpp)
@@ -10,6 +10,8 @@
// and this notice are preserved. This file is offered as-is, without any
// warranty.
#include <map>
#include <string_view>
template <typename T>
struct check {
@@ -55,4 +57,9 @@ void test();
void test() { func<foo>(0); }
}
int main() { return 0; }
int main() {
std::map<int, int> m;
m.emplace(2, 4);
auto [x, y] = *m.begin();
return 0;
}
+1 -1
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+3 -3
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
# limitations under the License.
#
cmake_minimum_required(VERSION 3.0)
project(perl_check)
cmake_minimum_required(VERSION 3.13)
project(perl_check LANGUAGES CXX)
set(CMAKE_VERBOSE_MAKEFILE true)
if(APPLE)
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
# Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+13 -8
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -50,16 +50,21 @@ execute_process(COMMAND "${brew}" --prefix python3
if(brew_python_f EQUAL 0)
find_package_message(brew_python "Python via Homebrew: ${brew_python}"
"${brew_python}")
list(APPEND Python_FRAMEWORKS_ADDITIONAL
list(APPEND Python3_FRAMEWORKS_ADDITIONAL
"${brew_python}/Frameworks/Python.framework")
endif()
execute_process(COMMAND "${brew}" --prefix qt5
RESULT_VARIABLE brew_qt5_f
OUTPUT_VARIABLE brew_qt5 OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
if(brew_qt5_f EQUAL 0)
find_package_message(brew_qt5 "Qt5 via Homebrew: ${brew_qt5}"
"${brew_qt5}")
if(DEFINED ENV{ZNC_QT_VER})
set(ZNC_QT_VER $ENV{ZNC_QT_VER})
else()
set(ZNC_QT_VER 6)
endif()
execute_process(COMMAND "${brew}" --prefix qt${ZNC_QT_VER}
RESULT_VARIABLE brew_qt_f
OUTPUT_VARIABLE brew_qt OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
if(brew_qt_f EQUAL 0)
find_package_message(brew_qt "Qt via Homebrew: ${brew_qt}"
"${brew_qt}")
endif()
execute_process(COMMAND "${brew}" --prefix gettext
Vendored Executable
+143
View File
@@ -0,0 +1,143 @@
#!/bin/sh
#
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# http://stackoverflow.com/questions/18993438/shebang-env-preferred-python-version
# http://stackoverflow.com/questions/12070516/conditional-shebang-line-for-different-versions-of-python
""":"
which python3 >/dev/null 2>&1 && exec python3 "$0" "$@"
which python >/dev/null 2>&1 && exec python "$0" "$@"
which python2 >/dev/null 2>&1 && exec python2 "$0" "$@"
echo "Error: configure wrapper requires python"
exec echo "Either install python, or use cmake directly"
":"""
import argparse
import os
import shutil
import subprocess
import sys
import re
extra_args = [os.path.dirname(sys.argv[0])]
parser = argparse.ArgumentParser()
def gnu_install_dir(name, cmake=None):
if cmake is None:
cmake = name.upper()
parser.add_argument('--' + name, action='append', metavar=cmake,
dest='cm_args',
type=lambda s: '-DCMAKE_INSTALL_{}={}'.format(cmake, s))
gnu_install_dir('prefix')
gnu_install_dir('bindir')
gnu_install_dir('sbindir')
gnu_install_dir('libexecdir')
gnu_install_dir('sysconfdir')
gnu_install_dir('sharedstatedir')
gnu_install_dir('localstatedir')
gnu_install_dir('libdir')
gnu_install_dir('includedir')
gnu_install_dir('oldincludedir')
gnu_install_dir('datarootdir')
gnu_install_dir('datadir')
gnu_install_dir('infodir')
gnu_install_dir('localedir')
gnu_install_dir('mandir')
gnu_install_dir('docdir')
group = parser.add_mutually_exclusive_group()
group.add_argument('--enable-debug', action='store_const', dest='build_type',
const='Debug', default='Release')
group.add_argument('--disable-debug', action='store_const', dest='build_type',
const='Release', default='Release')
def tristate(name, cmake=None):
if cmake is None:
cmake = name.upper()
group = parser.add_mutually_exclusive_group()
group.add_argument('--enable-' + name, action='append_const',
dest='cm_args', const='-DWANT_{}=YES'.format(cmake))
group.add_argument('--disable-' + name, action='append_const',
dest='cm_args', const='-DWANT_{}=NO'.format(cmake))
tristate('ipv6')
tristate('openssl')
tristate('zlib')
tristate('perl')
tristate('swig')
tristate('cyrus')
tristate('charset', 'ICU')
tristate('tcl')
tristate('i18n')
tristate('argon')
class HandlePython(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
extra_args.append('-DWANT_PYTHON=YES')
if values is not None:
extra_args.append('-DWANT_PYTHON_VERSION=' + values)
group = parser.add_mutually_exclusive_group()
group.add_argument('--enable-python', action=HandlePython, nargs='?',
metavar='PYTHON_VERSION')
group.add_argument('--disable-python', action='append_const', dest='cm_args',
const='-DWANT_PYTHON=NO')
parser.add_argument('--with-gtest', action='store', dest='gtest')
parser.add_argument('--with-gmock', action='store', dest='gmock')
class HandleSystemd(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
extra_args.append('-DWANT_SYSTEMD=YES')
if values is not None:
extra_args.append('-DWANT_SYSTEMD_DIR=' + values)
parser.add_argument('--with-systemdsystemunitdir', action=HandleSystemd,
nargs='?', metavar='UNITDIR')
def env_type(s):
name, value = s.split('=', 1)
return (name, value)
parser.add_argument('env', nargs='*', type=env_type, metavar='ENV_VAR=VALUE')
args = parser.parse_args()
if not shutil.which('cmake'):
print('CMake is required to proceed. Please install it via package manager,\n'
'or download the binary from https://cmake.org/')
sys.exit(1)
cm_args = args.cm_args or []
for env_key, env_value in args.env:
os.environ[env_key] = env_value
if args.gtest:
os.environ['GTEST_ROOT'] = args.gtest
if args.gmock:
os.environ['GMOCK_ROOT'] = args.gmock
if os.environ.get('CXX') is not None:
extra_args.append('-DCMAKE_CXX_COMPILER=' + os.environ['CXX'])
try:
os.remove('CMakeCache.txt')
except OSError:
pass
subprocess.check_call(['cmake', '-DCMAKE_BUILD_TYPE=' + args.build_type]
+ cm_args + extra_args)
-745
View File
@@ -1,745 +0,0 @@
dnl This redefines AC_PROG_CC to a version which errors out instead. This is
dnl because all our tests should be done with the C++ compiler. This should
dnl catch stuff which accidentally uses the C compiler.
AC_DEFUN([AC_PROG_CC], [m4_errprint(__file__:__line__[: Something is trying to use the C compiler. Since this is a C++ project, this should not happen!
])m4_exit(1)])
dnl Needed for AC_PATH_PROGS_FEATURE_CHECK which was added in 2.62
AC_PREREQ([2.62])
dnl Keep the version number in sync with version.h!
AC_INIT([znc], [1.7.x])
LIBZNC_VERSION=1.7
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/znc.cpp])
AC_LANG([C++])
AC_CONFIG_HEADERS([include/znc/zncconfig.h])
AH_TOP([#ifndef ZNCCONFIG_H
#define ZNCCONFIG_H])
AH_BOTTOM([#endif /* ZNCCONFIG_H */])
AC_DEFUN([ZNC_AUTO_FAIL], [
# This looks better in the summary at the end
$1="not found"
if test "x$old_$1" != "xauto" ; then
AC_MSG_ERROR([$2])
else
AC_MSG_WARN([$3])
fi
])
# AC_PROG_CXX sets CXXFLAGS to "-O2 -g" if it is unset which we don't want
CXXFLAGS="$CXXFLAGS "
AC_PROG_CXX
# "Optional" because we want custom error message
AX_CXX_COMPILE_STDCXX_11([noext], [optional])
if test x"$HAVE_CXX11" != x1; then
AC_MSG_ERROR([Upgrade your compiler. GCC 4.7+ and Clang 3.2+ are known to work.])
fi
appendLib () {
if test "$LIBS" != ""; then
LIBS="$LIBS $*"
else
LIBS=$*
fi
}
appendCXX () {
if test "$CXXFLAGS" != ""; then
CXXFLAGS="$CXXFLAGS $*"
else
CXXFLAGS=$*
fi
}
appendMod () {
if test "$MODFLAGS" != ""; then
MODFLAGS="$MODFLAGS $*"
else
MODFLAGS=$*
fi
}
appendLD () {
if test "$LDFLAGS" != ""; then
LDFLAGS="$LDFLAGS $*"
else
LDFLAGS=$*
fi
}
AC_PROG_INSTALL
AC_PROG_GREP
AC_PROG_SED
AC_CANONICAL_HOST
AC_SYS_LARGEFILE
ZNC_VISIBILITY
AC_PATH_PROG([GIT], [git])
PKG_PROG_PKG_CONFIG()
AC_ARG_ENABLE( [debug],
AS_HELP_STRING([--enable-debug], [enable debugging]),
[DEBUG="$enableval"],
[DEBUG="no"])
AC_ARG_ENABLE( [ipv6],
AS_HELP_STRING([--disable-ipv6], [disable ipv6 support]),
[IPV6="$enableval"],
[IPV6="yes"])
AC_ARG_ENABLE( [openssl],
AS_HELP_STRING([--disable-openssl], [disable openssl]),
[SSL="$enableval"],
[SSL="auto"])
AC_ARG_ENABLE( [zlib],
AS_HELP_STRING([--disable-zlib], [disable zlib]),
[ZLIB="$enableval"],
[ZLIB="auto"])
AC_ARG_ENABLE( [perl],
AS_HELP_STRING([--enable-perl], [enable perl]),
[PERL="$enableval"],
[PERL="no"])
AC_ARG_ENABLE( [python],
AS_HELP_STRING([--enable-python[[[=python3]]]], [enable python.
By default python3.pc of pkg-config is used, but you can use
another name, for example python-3.1]),
[PYTHON="$enableval"],
[PYTHON="no"])
AC_ARG_ENABLE( [swig],
AS_HELP_STRING([--enable-swig], [Enable automatic generation of source files needed for modperl/modpython.
This value is ignored if perl and python are disabled.
Usually no need to enable it.
]),
[USESWIG="$enableval"],
[USESWIG="auto"])
AC_ARG_ENABLE( [cyrus],
AS_HELP_STRING([--enable-cyrus], [enable cyrus]),
[if test "$enableval" = "yes" ; then CYRUS=1; fi],)
AC_ARG_ENABLE( [optimization],
AS_HELP_STRING([--disable-optimization], [Disable some compiler optimizations to
decrease memory usage while compiling]),
[OPTIMIZE="$enableval"],
[OPTIMIZE="yes"])
AC_ARG_ENABLE( [tdns],
AS_HELP_STRING([--disable-tdns], [disable threads usage for DNS resolving]),
[TDNS="$enableval"],
[TDNS="auto"])
AC_ARG_ENABLE( [run-from-source],
AS_HELP_STRING([--enable-run-from-source], [ZNC will be runnable without installation]),
[if test "x$enableval" = "xyes" ; then
AC_DEFINE([RUN_FROM_SOURCE], [1],
[Define if ZNC should be runnable without installation])
fi
RUNFROMSOURCE="$enableval"],
[RUNFROMSOURCE="no"])
AC_ARG_ENABLE( [poll],
AS_HELP_STRING([--disable-poll], [use select() instead of poll()]),
[POLL="$enableval"],
[POLL="yes"])
AC_ARG_WITH( [gtest],
AS_HELP_STRING([--with-gtest=DIR], [Path to directory with src/gtest-all.cc file.
If not specified, git submodule will be used.
If it is not available either, "make test" will fail.]))
if test "x$with_gtest" != xno; then
AC_SUBST([GTEST_DIR], [$with_gtest])
fi
AC_ARG_WITH([gmock],
AS_HELP_STRING([--with-gmock=DIR], [Path to directory with src/gmock-all.cc and src/gmock_main.cc files.
If not specified, git submodule will be used.
If it is not available either, "make test" will fail.]))
if test "x$with_gmock" != xno; then
AC_SUBST([GMOCK_DIR], [$with_gmock])
fi
AC_ARG_WITH([systemdsystemunitdir],
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
[
if test x"$with_systemdsystemunitdir" = xyes; then
with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
fi
])
if test "x$with_systemdsystemunitdir" != xno; then
AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
fi
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
case "${host_os}" in
freebsd*)
# -D__GNU_LIBRARY__ makes this work on fbsd 4.11
appendCXX -I/usr/local/include -D__GNU_LIBRARY__
appendLib -L/usr/local/lib -lcompat
appendMod -L/usr/local/lib
;;
solaris*)
appendLib -lsocket -lnsl -lresolv
ISSUN=1
;;
cygwin)
# We don't want to use -std=gnu++11 instead of -std=c++11, but among other things, -std=c++11 defines __STRICT_ANSI__ which makes cygwin not to compile: undefined references to strerror_r, to fdopen, to strcasecmp, etc (their declarations in system headers are between ifdef)
appendCXX -U__STRICT_ANSI__
ISCYGWIN=1
;;
darwin*)
ISDARWIN=1
AC_PATH_PROG([BREW], [brew])
if test -n "$BREW"; then
# add default homebrew paths
if test "x$HAVE_ICU" != "xno"; then
AC_MSG_CHECKING([icu4c via homebrew])
icu4c_prefix=`$BREW --prefix icu4c`
if test -n "$icu4c_prefix"; then
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$icu4c_prefix/lib/pkgconfig"
AC_MSG_RESULT([$icu4c_prefix])
else
AC_MSG_RESULT([no])
fi
fi
if test "x$PYTHON" != "xno"; then
brew_python_pc="$PYTHON"
# This is duplication of non-darwin python logic below...
if test "x$brew_python_pc" = "xyes"; then
brew_python_pc="python3"
fi
AC_MSG_CHECKING([python3 via homebrew])
python3_prefix=`$BREW --prefix python3`
if test -n "$python3_prefix"; then
python3_prefix=`find "$python3_prefix/" -name $brew_python_pc.pc | head -n1`
if test -n "$python3_prefix"; then
python3_prefix=`dirname "$python3_prefix"`
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$python3_prefix"
AC_MSG_RESULT([$python3_prefix])
else
AC_MSG_RESULT([no $brew_python_pc.pc found])
fi
else
AC_MSG_RESULT([no])
fi
fi
if test "x$SSL" != "xno"; then
AC_MSG_CHECKING([openssl via homebrew])
openssl_prefix=`$BREW --prefix openssl`
if test -n "$openssl_prefix"; then
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$openssl_prefix/lib/pkgconfig"
AC_MSG_RESULT([$openssl_prefix])
else
AC_MSG_RESULT([no])
fi
fi
fi
;;
esac
if test "$DEBUG" != "no"; then
appendCXX -ggdb3
AC_DEFINE([_DEBUG], [1], [Define for debugging])
if test "x$ISCYGWIN" != x1; then
# These enable some debug options in g++'s STL, e.g. invalid use of iterators
# But they cause crashes on cygwin while loading modules
AC_DEFINE([_GLIBCXX_DEBUG], [1], [Enable extra debugging checks in libstdc++])
AC_DEFINE([_GLIBCXX_DEBUG_PEDANTIC], [1], [Enable extra debugging checks in libstdc++])
fi
else
if test "x$OPTIMIZE" = "xyes"; then
appendCXX -O2
# In old times needed to define _FORTIFY_SOURCE to 2 ourself.
# Then GCC started to define it itself to 2. It was ok.
# But then GCC 4.7 started to define it to 0 or 2 depending on optimization level, and it started to conflict with our define.
AC_MSG_CHECKING([whether compiler predefines _FORTIFY_SOURCE])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
]], [[
#ifndef _FORTIFY_SOURCE
#error "Just checking, nothing fatal here"
#endif
]])
], [
AC_MSG_RESULT([yes])
], [
AC_MSG_RESULT([no])
appendCXX "-D_FORTIFY_SOURCE=2"
])
fi
fi
if test "$IPV6" != "no"; then
AC_DEFINE([HAVE_IPV6], [1], [Define if IPv6 support is enabled])
fi
if test "x$GXX" = "xyes"; then
appendCXX -Wall -W -Wno-unused-parameter -Woverloaded-virtual -Wshadow
fi
if test "$POLL" = "yes"; then
# poll() is broken on Mac OS, it fails with POLLNVAL for pipe()s.
if test -n "$ISDARWIN"
then
# Did they give us --enable-poll?
if test -n "$enable_poll"
then
# Yes, they asked for this.
AC_MSG_WARN([poll() is known to be broken on Mac OS X. You have been warned.])
else
# No, our default value of "yes" got applied.
AC_MSG_WARN([poll() is known to be broken on Mac OS X. Using select() instead.])
AC_MSG_WARN([Use --enable-poll for forcing poll() to be used.])
POLL=no
fi
fi
if test "$POLL" = "yes"; then
AC_DEFINE([CSOCK_USE_POLL], [1], [Use poll() instead of select()])
fi
fi
AC_CHECK_LIB( gnugetopt, getopt_long,)
AC_CHECK_FUNCS([lstat getopt_long getpassphrase clock_gettime tcsetattr])
# ----- Check for dlopen
AC_SEARCH_LIBS([dlopen], [dl], [],
[AC_MSG_ERROR([Could not find dlopen. ZNC will not work on this box until you upgrade this ancient system or at least install the necessary system libraries.])])
# ----- Check for pthreads
AX_PTHREAD([
AC_DEFINE([HAVE_PTHREAD], [1], [Define if you have POSIX threads libraries and header files.])
appendCXX "$PTHREAD_CFLAGS"
appendLib "$PTHREAD_LIBS"
], [
AC_MSG_ERROR([This compiler/OS doesn't seem to support pthreads.])
])
# Note that old broken systems, such as OpenBSD, NetBSD, which don't support AI_ADDRCONFIG, also have thread-unsafe getaddrinfo().
# Gladly, they fixed thread-safety before support of AI_ADDRCONFIG, so this can be abused to detect the thread-safe getaddrinfo().
#
# TODO: drop support of blocking DNS at some point. OpenBSD supports AI_ADDRCONFIG since Nov 2014, and their getaddrinfo() is thread-safe since Nov 2013. NetBSD's one is thread-safe since ages ago.
DNS_TEXT=blocking
if test "x$TDNS" != "xno"; then
old_TDNS=$TDNS
AC_MSG_CHECKING([whether getaddrinfo() supports AI_ADDRCONFIG])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
]], [[
int x = AI_ADDRCONFIG;
(void) x;
]])
], [
AC_MSG_RESULT([yes])
TDNS=yes
], [
AC_MSG_RESULT([no])
TDNS=no
])
if test "x$TDNS" = "xyes"; then
DNS_TEXT=threads
AC_DEFINE([HAVE_THREADED_DNS], [1], [Define if threaded DNS is enabled])
else
ZNC_AUTO_FAIL([TDNS],
[support for threaded DNS not found. Try --disable-tdns.
Disabling it may result in a slight performance decrease but will not have any other side-effects],
[support for threaded DNS not found, so DNS resolving will be blocking])
fi
fi
# ----- Check for openssl
SSL_TEXT="$SSL"
if test "x$SSL" != "xno"; then
old_SSL=$SSL
PKG_CHECK_MODULES([openssl], [openssl], [
appendLib "$openssl_LIBS"
appendCXX "$openssl_CFLAGS"
], [
# Don't reorder this!
# On some arches libssl depends on libcrypto without linking to it :(
AC_CHECK_LIB( crypto, BIO_new,, SSL=no ; SSL_TEXT="no (libcrypt not found)" )
AC_CHECK_LIB( ssl, SSL_shutdown,, SSL=no ; SSL_TEXT="no (libssl not found)" )
])
if test "x$SSL" != "xno"; then
AC_MSG_CHECKING([whether openssl is usable])
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
#include <openssl/ssl.h>
]], [[
SSL_CTX* ctx = SSL_CTX_new(TLSv1_method());
SSL* ssl = SSL_new(ctx);
DH* dh = DH_new();
DH_free(dh);
SSL_free(ssl);
SSL_CTX_free(ctx);
]])
], [
AC_MSG_RESULT([yes])
], [
AC_MSG_RESULT([no])
SSL=no
SSL_TEXT="no (openssl not usable)"
])
fi
if test "x$SSL" = "xno" ; then
ZNC_AUTO_FAIL([SSL],
[OpenSSL not found. Try --disable-openssl.],
[OpenSSL was not found and thus disabled])
NOSSL=1
else
AC_DEFINE([HAVE_LIBSSL], [1], [Define if openssl is enabled])
SSL=yes
SSL_TEXT=yes
fi
else
NOSSL=1
SSL_TEXT="no (explicitly disabled)"
fi
# ----- Check for zlib
old_ZLIB="$ZLIB"
ZLIB_TEXT="$ZLIB"
if test "x$ZLIB" != "xno"; then
AC_MSG_CHECKING([whether zlib is usable])
my_saved_LIBS="$LIBS"
appendLib "-lz"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include "zlib.h"
]], [[
z_stream zs;
(void) deflateInit2(&zs, 0, 0, 0, 0, 0);
(void) deflate(&zs, 0);
]])
], [
AC_MSG_RESULT([yes])
ZLIB=yes
ZLIB_TEXT=yes
], [
AC_MSG_RESULT([no])
ZLIB=no
ZLIB_TEXT="no (libz not found)"
])
if test "x$ZLIB" = "xno"; then
ZNC_AUTO_FAIL([ZLIB],
[zlib was not found. Try --disable-zlib],
[zlib was not found and thus disabled])
LIBS="$my_saved_LIBS"
else
AC_DEFINE([HAVE_ZLIB], [1], [Define if zlib is available])
fi
fi
AC_ARG_ENABLE( [charset],
AS_HELP_STRING([--disable-charset], [disable ICU support]),
[HAVE_ICU="$enableval"],
[HAVE_ICU="auto"])
if test "x$HAVE_ICU" != "xno"
then
old_HAVE_ICU="$HAVE_ICU"
PKG_CHECK_MODULES([icu], [icu-uc], [
appendLib "$icu_LIBS"
appendCXX "$icu_CFLAGS"
HAVE_ICU=yes
AC_DEFINE([HAVE_ICU], [1], [Enable ICU library for Unicode handling])
AC_DEFINE([U_USING_ICU_NAMESPACE], [0], [Do not clutter global namespace with ICU C++ stuff])
], [
ZNC_AUTO_FAIL([HAVE_ICU],
[support for charset conversion not found. Try --disable-charset.],
[support for charset conversion not found and thus disabled])
HAVE_ICU="no (icu-uc not found via pkg-config)"
])
fi
# For integration test only
PKG_CHECK_MODULES([qt], [Qt5Network >= 5.4], [], [:])
AC_ARG_WITH( [module-prefix],
AS_HELP_STRING([--with-module-prefix], [module object code [LIBDIR/znc]]),
[MODDIR=$withval],
[MODDIR="${libdir}/znc"] )
AC_ARG_WITH( [module-data-prefix],
AS_HELP_STRING([--with-module-data-prefix=DIR],
[static module data (webadmin skins) [DATADIR/znc]]),
[DATADIR=$withval],
[DATADIR="${datadir}/znc"] )
appendMod "$CXXFLAGS"
appendMod "$CFLAG_VISIBILITY"
if test -z "$ISSUN" -a -z "$ISDARWIN" -a -z "$ISCYGWIN"; then
# This is an unknown compiler flag on some OS
appendLD -Wl,--export-dynamic
fi
if test -z "$ISCYGWIN" ; then
# cygwin doesn't need -fPIC, everything else does (for modules)
# warning: -fPIC ignored for target (all code is position independent)
appendMod -fPIC
else
# But cygwin does want most of ZNC in a shared lib
# See https://cygwin.com/ml/cygwin-apps/2015-07/msg00108.html for the reasoning behind the name.
LIBZNC="cygznc-${LIBZNC_VERSION}.dll"
LIBZNCDIR="$bindir"
# See above about __STRICT_ANSI__
qt_CFLAGS="$qt_CFLAGS -U__STRICT_ANSI__"
fi
if test -z "$ISDARWIN"; then
MODLINK="-shared"
else
# Mac OS X differentiates between shared libs (-dynamiclib)
# and loadable modules (-bundle).
MODLINK="-bundle -flat_namespace -undefined suppress"
# TODO test if -twolevel_namespace and/or
# -undefined dynamic_lookup work
# (dynamic_lookup might only work on 10.4 and later)
fi
if test "x$PERL" != xno -o "x$PYTHON" != xno; then
old_USESWIG="$USESWIG"
if test "x$USESWIG" != "xno"; then
AC_PROG_SWIG([3.0.0])
test -z "$SWIG" && USESWIG=no
if test "x$USESWIG" = xno -a "x$old_USESWIG" = yes; then
AC_MSG_ERROR([Could not found appropriate SWIG installation. Check config.log for details.])
fi
fi
if test -r "$srcdir/modules/modperl/generated.tar.gz" -a -r "$srcdir/modules/modpython/generated.tar.gz"; then
AC_MSG_NOTICE([modperl/modpython files are found, disabling SWIG])
USESWIG=no
fi
if test "x$USESWIG" = xno; then
if test ! -r "$srcdir/modules/modperl/generated.tar.gz" -o ! -r "$srcdir/modules/modpython/generated.tar.gz"; then
AC_MSG_ERROR([Can not build modperl/modpython. Either install SWIG, or build ZNC from a tarball, or disable modperl/modpython. Check config.log for details.])
else
AC_MSG_NOTICE([modperl/modpython files are found, no SWIG needed])
fi
USESWIG="not needed"
SWIG=""
else
USESWIG=yes
fi
else
if test "x$USESWIG" = "xyes"; then
AC_MSG_WARN([swig is used only for perl and python, but both are disabled. Disabling swig.])
fi
USESWIG='not needed'
fi
PERL_TEXT="$PERL"
if test "x$PERL" != "xno"; then
old_PERL="$PERL"
AC_PATH_PROG([PERL_BINARY], [perl], [])
if test -n "$PERL_BINARY" && eval "$PERL_BINARY -e'use 5.010'"; then
my_saved_LDFLAGS="$LDFLAGS"
appendLD `$PERL_BINARY -MExtUtils::Embed -e ccopts -e ldopts`
AC_CHECK_LIB(perl, perl_alloc,
[: No, we do not want autoconf to do sth automatically],
PERL="no" ; PERL_TEXT="no (libperl not found)")
LDFLAGS="$my_saved_LDFLAGS"
else
PERL="no"
PERL_TEXT="no (perl binary not found or too old)"
fi
if test "x$PERL" = "xno"; then
ZNC_AUTO_FAIL([PERL],
[perl not found. Try --disable-perl.],
[perl was not found and thus disabled])
PERL_BINARY=""
else
PERL="yes"
PERL_TEXT="yes"
fi
fi
PYTHON_TEXT="$PYTHON"
if test "x$PYTHON" != "xno"; then
# Default value for just --enable-python
if test "x$PYTHON" = "xyes"; then
PYTHON="python3"
fi
old_PYTHON="$PYTHON"
if test -z "$PKG_CONFIG"; then
AC_MSG_ERROR([pkg-config is required for modpython.])
fi
PKG_CHECK_MODULES([python], [$PYTHON >= 3.0],, AC_MSG_ERROR([$PYTHON.pc not found or is wrong. Try --disable-python or install python3.]))
my_saved_LIBS="$LIBS"
my_saved_CXXFLAGS="$CXXFLAGS"
appendLib $python_LIBS
appendCXX $python_CFLAGS
AC_CHECK_FUNC([Py_Initialize], [], [PYTHON="no" ; PYTHON_TEXT="no (libpython not found)"])
if test "x$PYTHON" != "xno"; then
# Yes, modpython depends on perl.
AC_PATH_PROG([PERL_BINARY], [perl])
if test -z "$PERL_BINARY"; then
AC_MSG_ERROR([To compile modpython you need to be able to execute perl scripts. Try --disable-python or install perl.])
fi
LIBS="$my_saved_LIBS"
CXXFLAGS="$my_saved_CXXFLAGS"
fi
if test "x$HAVE_ICU" != "xyes"; then
AC_MSG_ERROR([Modpython requires ZNC to be compiled with charset support, but ICU library not found. Try --disable-python or install libicu.])
fi
if test "x$PYTHON" = "xno"; then
ZNC_AUTO_FAIL([PYTHON],
[python not found. Try --disable-python.],
[python was not found and thus disabled])
PYTHONCFG_BINARY=""
else
PYTHON="yes"
PYTHON_TEXT="yes"
fi
fi
if test -n "$CYRUS"; then
AC_CHECK_LIB( sasl2, sasl_server_init,
[: Dont let autoconf add -lsasl2, Makefile handles that],
AC_MSG_ERROR([could not find libsasl2. Try --disable-cyrus.]))
fi
# Check if we want modtcl
AC_ARG_ENABLE( [tcl],
AS_HELP_STRING([--enable-tcl], [enable modtcl]),
[TCL="$enableval"],
[TCL="no"])
AC_ARG_WITH( [tcl-flags],
AS_HELP_STRING([--with-tcl-flags=FLAGS],
[The flags needed for compiling and linking modtcl]),
[TCL_FLAGS="$withval"],)
if test x"$TCL" = "xyes"
then
AC_ARG_WITH( [tcl],
AS_HELP_STRING([--with-tcl=DIR],
[directory containing tclConfig.sh]),
TCL_DIR="${withval}")
# This will need to be extended in the future, but I don't think
# it's a good idea to stuff a shitload of random stuff in here right now
for path in $TCL_DIR /usr/lib /usr/lib/tcl8.4 /usr/lib/tcl8.5 /usr/lib/tcl8.6
do
file="${path}/tclConfig.sh"
AC_MSG_CHECKING([for ${file}])
if test -r ${file}
then
TCL_CONF=${file}
AC_MSG_RESULT([yes])
break
fi
AC_MSG_RESULT([no])
done
if test x"${TCL_CONF}" = x
then
# They --enable-tcl'd, so give them some sane default
TCL_FLAGS="-I/usr/include/tcl -ltcl"
AC_MSG_WARN([Could not find tclConfig.sh, using some sane defaults.])
else
AC_MSG_CHECKING([modtcl flags])
. ${TCL_CONF}
# eval because those vars depend on other vars in there
eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
eval "TCL_INCLUDE_SPEC=\"${TCL_INCLUDE_SPEC}\""
TCL_FLAGS="$TCL_INCLUDE_SPEC $TCL_LIB_SPEC"
AC_MSG_RESULT([$TCL_FLAGS])
fi
my_saved_LIBS="$LIBS"
appendLib "$TCL_FLAGS"
AC_CHECK_FUNC([Tcl_CreateInterp], [TCL_TEST=yes], [TCL_TEST=no])
if test x"$TCL_TEST" = "xno"; then
AC_MSG_ERROR([tcl not found, try --disable-tcl, or install tcl properly. If tcl is installed to a non-standard path, use --enable-tcl --with-tcl=/path])
fi
LIBS="$my_saved_LIBS"
fi
AC_CACHE_CHECK([for GNU make], [ac_cv_path_GNUMAKE], [
AC_PATH_PROGS_FEATURE_CHECK([GNUMAKE], [make gmake], [[
if $ac_path_GNUMAKE --version | $GREP GNU > /dev/null; then
ac_cv_path_GNUMAKE=$ac_path_GNUMAKE
ac_path_GNUMAKE_found=:
fi
]], [AC_MSG_ERROR([could not find GNU make])]
)
])
GNUMAKE=`echo $ac_cv_path_GNUMAKE | $SED "s%.*/%%"`
# this is in the end, for not trying to include it when it doesn't exist yet
appendCXX "-include znc/zncconfig.h"
appendMod "-include znc/zncconfig.h"
AC_SUBST([CXXFLAGS])
AC_SUBST([CPPFLAGS])
AC_SUBST([MODFLAGS])
AC_SUBST([LDFLAGS])
AC_SUBST([LIBS])
AC_SUBST([LIBZNC])
AC_SUBST([LIBZNCDIR])
AC_SUBST([ISCYGWIN])
AC_SUBST([MODLINK])
AC_SUBST([NOSSL])
AC_SUBST([TCL_FLAGS])
AC_SUBST([CYRUS])
AC_SUBST([MODDIR])
AC_SUBST([DATADIR])
AC_SUBST([PERL])
AC_SUBST([PYTHON])
AC_SUBST([SWIG])
AC_SUBST([python_CFLAGS])
AC_SUBST([python_LIBS])
AC_SUBST([qt_CFLAGS])
AC_SUBST([qt_LIBS])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([znc-buildmod])
AC_CONFIG_FILES([man/Makefile])
AC_CONFIG_FILES([znc.pc])
AC_CONFIG_FILES([znc-uninstalled.pc])
AC_CONFIG_FILES([modules/Makefile])
AC_OUTPUT
if test "x$ISCYGWIN" = x1; then
# Side effect of undefining __STRICT_ANSI__
# http://llvm.org/bugs/show_bug.cgi?id=13530
echo >> include/znc/zncconfig.h
echo '#ifndef ZNCCONFIG_H_ADDITIONS' >> include/znc/zncconfig.h
echo '#define ZNCCONFIG_H_ADDITIONS' >> include/znc/zncconfig.h
echo '#ifdef __clang__' >> include/znc/zncconfig.h
echo 'struct __float128;' >> include/znc/zncconfig.h
echo '#endif' >> include/znc/zncconfig.h
echo '#endif' >> include/znc/zncconfig.h
fi
echo
echo ZNC AC_PACKAGE_VERSION configured
echo
echo "prefix: $prefix"
echo "debug: $DEBUG"
echo "ipv6: $IPV6"
echo "openssl: $SSL_TEXT"
echo "dns: $DNS_TEXT"
echo "perl: $PERL_TEXT"
echo "python: $PYTHON_TEXT"
echo "swig: $USESWIG"
if test x"$CYRUS" = "x" ; then
echo "cyrus: no"
else
echo "cyrus: yes"
fi
if test x"$TCL_FLAGS" = "x" ; then
echo "tcl: no"
else
echo "tcl: yes"
fi
echo "charset: $HAVE_ICU"
echo "zlib: $ZLIB_TEXT"
echo "run from src: $RUNFROMSOURCE"
echo
echo "Now you can run \"$GNUMAKE\" to compile ZNC"
-136
View File
@@ -1,136 +0,0 @@
#!/bin/sh
#
# Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# http://stackoverflow.com/questions/18993438/shebang-env-preferred-python-version
# http://stackoverflow.com/questions/12070516/conditional-shebang-line-for-different-versions-of-python
""":"
which python3 >/dev/null 2>&1 && exec python3 "$0" "$@"
which python >/dev/null 2>&1 && exec python "$0" "$@"
which python2 >/dev/null 2>&1 && exec python2 "$0" "$@"
echo "Error: configure wrapper requires python"
exec echo "Either install python, or use cmake directly"
":"""
import argparse
import os
import subprocess
import sys
import re
extra_args = [os.path.dirname(sys.argv[0])]
parser = argparse.ArgumentParser()
def gnu_install_dir(name, cmake=None):
if cmake is None:
cmake = name.upper()
parser.add_argument('--' + name, action='append', metavar=cmake,
dest='cm_args',
type=lambda s: '-DCMAKE_INSTALL_{}={}'.format(cmake, s))
gnu_install_dir('prefix')
gnu_install_dir('bindir')
gnu_install_dir('sbindir')
gnu_install_dir('libexecdir')
gnu_install_dir('sysconfdir')
gnu_install_dir('sharedstatedir')
gnu_install_dir('localstatedir')
gnu_install_dir('libdir')
gnu_install_dir('includedir')
gnu_install_dir('oldincludedir')
gnu_install_dir('datarootdir')
gnu_install_dir('datadir')
gnu_install_dir('infodir')
gnu_install_dir('localedir')
gnu_install_dir('mandir')
gnu_install_dir('docdir')
group = parser.add_mutually_exclusive_group()
group.add_argument('--enable-debug', action='store_const', dest='build_type',
const='Debug', default='Release')
group.add_argument('--disable-debug', action='store_const', dest='build_type',
const='Release', default='Release')
def tristate(name, cmake=None):
if cmake is None:
cmake = name.upper()
group = parser.add_mutually_exclusive_group()
group.add_argument('--enable-' + name, action='append_const',
dest='cm_args', const='-DWANT_{}=YES'.format(cmake))
group.add_argument('--disable-' + name, action='append_const',
dest='cm_args', const='-DWANT_{}=NO'.format(cmake))
tristate('ipv6')
tristate('openssl')
tristate('zlib')
tristate('perl')
tristate('swig')
tristate('cyrus')
tristate('charset', 'ICU')
tristate('tcl')
tristate('i18n')
class HandlePython(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
extra_args.append('-DWANT_PYTHON=YES')
if values is not None:
extra_args.append('-DWANT_PYTHON_VERSION=' + values)
group = parser.add_mutually_exclusive_group()
group.add_argument('--enable-python', action=HandlePython, nargs='?',
metavar='PYTHON_VERSION')
group.add_argument('--disable-python', action='append_const', dest='cm_args',
const='-DWANT_PYTHON=NO')
parser.add_argument('--with-gtest', action='store', dest='gtest')
parser.add_argument('--with-gmock', action='store', dest='gmock')
class HandleSystemd(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
extra_args.append('-DWANT_SYSTEMD=YES')
if values is not None:
extra_args.append('-DWANT_SYSTEMD_DIR=' + values)
parser.add_argument('--with-systemdsystemunitdir', action=HandleSystemd,
nargs='?', metavar='UNITDIR')
def env_type(s):
name, value = s.split('=', 1)
return (name, value)
parser.add_argument('env', nargs='*', type=env_type, metavar='ENV_VAR=VALUE')
args = parser.parse_args()
cm_args = args.cm_args or []
for env_key, env_value in args.env:
os.environ[env_key] = env_value
if args.gtest:
os.environ['GTEST_ROOT'] = args.gtest
if args.gmock:
os.environ['GMOCK_ROOT'] = args.gmock
if os.environ.get('CXX') is not None:
extra_args.append('-DCMAKE_CXX_COMPILER=' + os.environ['CXX'])
try:
os.remove('CMakeCache.txt')
except OSError:
pass
subprocess.check_call(['cmake', '-DCMAKE_BUILD_TYPE=' + args.build_type]
+ cm_args + extra_args)
+1
View File
@@ -0,0 +1 @@
./configure
Submodule
+1
Submodule docker added at 8638ba43ac
+1 -1
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+31 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
#include <znc/Nick.h>
#include <znc/ZNCString.h>
#include <znc/Buffer.h>
#include <znc/Translation.h>
#include <map>
// Forward Declarations
@@ -31,7 +32,7 @@ class CConfig;
class CFile;
// !Forward Declarations
class CChan {
class CChan : private CCoreTranslationMixin {
public:
typedef enum {
Voice = '+',
@@ -75,10 +76,24 @@ class CChan {
const CString& sHost);
// Modes
/// @deprecated Use SetModes(CString, VCString)
void SetModes(const CString& s);
/**
* Set the current modes for this channel
* @param sModes The mode characters being changed
* @param vsModeParams The parameters for the modes to be set
*/
void SetModes(const CString& sModes, const VCString& vsModeParams);
/// @deprecated Use ModeChange(CString, VCString, CNick*)
void ModeChange(const CString& sModes, const CNick* OpNick = nullptr);
bool AddMode(unsigned char uMode, const CString& sArg);
bool RemMode(unsigned char uMode);
/**
* Handle changing the modes on a channel
* @param sModes The mode string (eg. +ovbs-pbo)
* @param vsModeParams The parameters for the mode string
*/
void ModeChange(const CString& sModes,const VCString& vsModeParams, const CNick* OpNick = nullptr);
bool AddMode(char cMode, const CString& sArg);
bool RemMode(char cMode);
CString GetModeString() const;
CString GetModeArg(CString& sArgs) const;
CString GetModeForNames() const;
@@ -120,10 +135,14 @@ class CChan {
// !Buffer
// m_Nick wrappers
/// e.g. '@' for chanop.
CString GetPermStr() const { return m_Nick.GetPermStr(); }
bool HasPerm(unsigned char uPerm) const { return m_Nick.HasPerm(uPerm); }
bool AddPerm(unsigned char uPerm) { return m_Nick.AddPerm(uPerm); }
bool RemPerm(unsigned char uPerm) { return m_Nick.RemPerm(uPerm); }
/// e.g. '@' for chanop.
bool HasPerm(char cPerm) const { return m_Nick.HasPerm(cPerm); }
/// e.g. '@' for chanop.
bool AddPerm(char cPerm) { return m_Nick.AddPerm(cPerm); }
/// e.g. '@' for chanop.
bool RemPerm(char cPerm) { return m_Nick.RemPerm(cPerm); }
// !wrappers
// Setters
@@ -154,14 +173,14 @@ class CChan {
// Getters
CIRCNetwork* GetNetwork() const { return m_pNetwork; }
bool IsModeKnown() const { return m_bModeKnown; }
bool HasMode(unsigned char uMode) const;
bool HasMode(char cMode) const;
CString GetOptions() const;
CString GetModeArg(unsigned char uMode) const;
CString GetModeArg(char cMode) const;
std::map<char, unsigned int> GetPermCounts() const;
bool IsOn() const { return m_bIsOn; }
const CString& GetName() const { return m_sName; }
const std::map<unsigned char, CString>& GetModes() const {
return m_musModes;
const std::map<char, CString>& GetModes() const {
return m_mcsModes;
}
const CString& GetKey() const { return m_sKey; }
const CString& GetTopic() const { return m_sTopic; }
@@ -204,7 +223,7 @@ class CChan {
CBuffer m_Buffer;
bool m_bModeKnown;
std::map<unsigned char, CString> m_musModes;
std::map<char, CString> m_mcsModes;
};
#endif // !ZNC_CHAN_H
+79 -84
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ class CMessage;
class CChan;
// !Forward Declarations
class CAuthBase {
class CAuthBase : private CCoreTranslationMixin {
public:
CAuthBase(const CString& sUsername, const CString& sPassword,
CZNCSock* pSock)
@@ -98,71 +98,7 @@ class CClientAuth : public CAuthBase {
class CClient : public CIRCSocket {
public:
CClient()
: CIRCSocket(),
m_bGotPass(false),
m_bGotNick(false),
m_bGotUser(false),
m_bInCap(false),
m_bCapNotify(false),
m_bAwayNotify(false),
m_bAccountNotify(false),
m_bExtendedJoin(false),
m_bNamesx(false),
m_bUHNames(false),
m_bAway(false),
m_bServerTime(false),
m_bBatch(false),
m_bEchoMessage(false),
m_bSelfMessage(false),
m_bPlaybackActive(false),
m_pUser(nullptr),
m_pNetwork(nullptr),
m_sNick("unknown-nick"),
m_sPass(""),
m_sUser(""),
m_sNetwork(""),
m_sIdentifier(""),
m_spAuth(),
m_ssAcceptedCaps(),
m_ssSupportedTags(),
m_mCoreCaps({
{"multi-prefix",
{false, [this](bool bVal) { m_bNamesx = bVal; }}},
{"userhost-in-names",
{false, [this](bool bVal) { m_bUHNames = bVal; }}},
{"echo-message",
{false, [this](bool bVal) { m_bEchoMessage = bVal; }}},
{"server-time",
{false, [this](bool bVal) {
m_bServerTime = bVal;
SetTagSupport("time", bVal);
}}},
{"batch", {false, [this](bool bVal) {
m_bBatch = bVal;
SetTagSupport("batch", bVal);
}}},
{"cap-notify",
{false, [this](bool bVal) { m_bCapNotify = bVal; }}},
{"away-notify",
{true, [this](bool bVal) { m_bAwayNotify = bVal; }}},
{"account-notify",
{true, [this](bool bVal) { m_bAccountNotify = bVal; }}},
{"extended-join",
{true, [this](bool bVal) { m_bExtendedJoin = bVal; }}},
}) {
EnableReadLine();
// RFC says a line can have 512 chars max, but we are
// a little more gentle ;)
SetMaxBufferThreshold(1024);
// For compatibility with older clients
m_mCoreCaps["znc.in/server-time-iso"] = m_mCoreCaps["server-time"];
m_mCoreCaps["znc.in/batch"] = m_mCoreCaps["batch"];
m_mCoreCaps["znc.in/self-message"] = {
false, [this](bool bVal) { m_bSelfMessage = bVal; }};
}
CClient();
virtual ~CClient();
CClient(const CClient&) = delete;
@@ -175,12 +111,15 @@ class CClient : public CIRCSocket {
CString GetNick(bool bAllowIRCNick = true) const;
CString GetNickMask() const;
CString GetIdentifier() const { return m_sIdentifier; }
unsigned short int CapVersion() const { return m_uCapVersion; }
bool HasCap302() const { return CapVersion() >= 302; }
bool HasCapNotify() const { return m_bCapNotify; }
bool HasAwayNotify() const { return m_bAwayNotify; }
bool HasAccountNotify() const { return m_bAccountNotify; }
bool HasExtendedJoin() const { return m_bExtendedJoin; }
bool HasNamesx() const { return m_bNamesx; }
bool HasUHNames() const { return m_bUHNames; }
bool HasChgHost() const { return m_bChgHost; }
bool IsAway() const { return m_bAway; }
bool HasServerTime() const { return m_bServerTime; }
bool HasBatch() const { return m_bBatch; }
@@ -199,14 +138,23 @@ class CClient : public CIRCSocket {
void SetPlaybackActive(bool bActive) { m_bPlaybackActive = bActive; }
void PutIRC(const CString& sLine);
// Strips prefix and potentially tags before sending to server.
void PutIRCStripping(CMessage Message);
/** Sends a raw data line to the client.
* @param sLine The line to be sent.
*
* The line is first passed \e unmodified to the \ref CModule::OnSendToClient()
* module hook. If no module halts the process, the line is then sent to the client.
* The line is first passed \e unmodified to the \ref
* CModule::OnSendToClient() module hook. If no module halts the process,
* the line is then sent to the client.
*
* These lines appear in the debug output in the following syntax:
* \code [time] (user/network) ZNC -> CLI [line] \endcode
*
* Prefer \l PutClient() instead.
*/
bool PutClientRaw(const CString& sLine);
/** Sends a message to the client.
* See \l PutClient(const CMessage&) for details.
*/
void PutClient(const CString& sLine);
/** Sends a message to the client.
@@ -245,14 +193,17 @@ class CClient : public CIRCSocket {
* ----------- | ----------
* \c time | \l CClient::HasServerTime() (<a href="http://ircv3.net/specs/extensions/server-time-3.2.html">server-time</a>)
* \c batch | \l CClient::HasBatch() (<a href="http://ircv3.net/specs/extensions/batch-3.2.html">batch</a>)
*
* Additional tags can be added via \l CClient::SetTagSupport().
*
* @warning Bypassing the filter may cause troubles to some older IRC clients.
* @warning Bypassing the filter may cause troubles to some older IRC
* clients.
*
* It is possible to bypass the filter by converting a message to a string
* using \l CMessage::ToString(), and passing the resulting raw line to the
* \l CClient::PutClient(const CString& sLine) overload:
* \l CClient::PutClientRaw(const CString& sLine):
* \code
* pClient->PutClient(Message.ToString());
* pClient->PutClientRaw(Message.ToString());
* \endcode
*/
bool PutClient(const CMessage& Message);
@@ -269,14 +220,16 @@ class CClient : public CIRCSocket {
bool IsTagEnabled(const CString& sTag) const {
return 1 == m_ssSupportedTags.count(sTag);
}
/** Registers a tag as being supported or unsupported by a client.
/** Registers a tag as being supported or unsupported by the client.
* This doesn't affect tags which the client sends.
* @param sTag The tag to register.
* @param bState Whether the client supports the tag.
*/
void SetTagSupport(const CString& sTag, bool bState);
void NotifyServerDependentCaps(const SCString& ssCaps);
void ClearServerDependentCaps();
/** Notifies client about one specific cap which server has just notified us about.
*/
void NotifyServerDependentCap(const CString& sCap, bool bValue, const CString& sValue);
void ReadLine(const CString& sData) override;
bool SendMotd();
@@ -299,11 +252,33 @@ class CClient : public CIRCSocket {
CIRCSock* GetIRCSock();
CString GetFullName() const;
/** Sends AUTHENTIATE message to client.
* It encodes it to Base64 and splits to multiple IRC messages if necessary.
*/
void SendSASLChallenge(CString sMessage);
void RefuseSASLLogin(const CString& sReason);
void AcceptSASLLogin(CUser& User);
/** Start potentially asynchronous process of checking the credentials.
* When finished, will send the success/failure SASL numerics to the
* client. This is mostly useful for SASL PLAIN.
* sAuthorizationId is internally passed through ParseUser() to extract
* network and client id.
* Currently sUser should match the username from
* sAuthorizationId: either in full, or just the username part; but in a
* future version we may add an ability to actually login as a different
* user, but with your password.
*/
void StartSASLPasswordCheck(const CString& sUser, const CString& sPassword,
const CString& sAuthorizationId);
/** Gathers username, client id, network name, if present. Returns username
* cleaned from client id and network name.
*/
CString ParseUser(const CString& sAuthLine);
private:
void HandleCap(const CMessage& Message);
void RespondCap(const CString& sResponse);
void ParsePass(const CString& sAuthLine);
void ParseUser(const CString& sAuthLine);
void ParseIdentifier(const CString& sAuthLine);
template <typename T>
@@ -315,6 +290,15 @@ class CClient : public CIRCSocket {
unsigned int DetachChans(const std::set<CChan*>& sChans);
bool OnActionMessage(CActionMessage& Message);
void OnAuthenticateMessage(const CAuthenticateMessage& Message);
void AbortSASL(const CString& sFullIRCLine);
bool IsDuringSASL() const { return !m_sSASLMechanism.empty(); }
/**
* Returns set of all available SASL mechanisms.
*/
SCString EnumerateSASLMechanisms() const;
bool OnCTCPMessage(CCTCPMessage& Message);
bool OnJoinMessage(CJoinMessage& Message);
bool OnModeMessage(CModeMessage& Message);
@@ -323,6 +307,7 @@ class CClient : public CIRCSocket {
bool OnPingMessage(CMessage& Message);
bool OnPongMessage(CMessage& Message);
bool OnQuitMessage(CQuitMessage& Message);
bool OnTagMessage(CTargetMessage& Message);
bool OnTextMessage(CTextMessage& Message);
bool OnTopicMessage(CTopicMessage& Message);
bool OnOtherMessage(CMessage& Message);
@@ -331,6 +316,7 @@ class CClient : public CIRCSocket {
bool m_bGotPass;
bool m_bGotNick;
bool m_bGotUser;
unsigned short int m_uCapVersion;
bool m_bInCap;
bool m_bCapNotify;
bool m_bAwayNotify;
@@ -338,32 +324,41 @@ class CClient : public CIRCSocket {
bool m_bExtendedJoin;
bool m_bNamesx;
bool m_bUHNames;
bool m_bChgHost;
bool m_bAway;
bool m_bServerTime;
bool m_bBatch;
bool m_bEchoMessage;
bool m_bSelfMessage;
bool m_bMessageTagCap;
bool m_bSASLCap;
bool m_bPlaybackActive;
CUser* m_pUser;
CIRCNetwork* m_pNetwork;
CString m_sNick;
CString m_sPass;
// User who didn't necessarily login yet, or might not even exist.
CString m_sUser;
CString m_sNetwork;
CString m_sIdentifier;
CString m_sSASLBuffer;
// Set while the exchange is in progress
CString m_sSASLMechanism;
// Username who successfully logged in using SASL. This is not a CUser*
// because between the 903 and CAP END the user could have been deleted.
CString m_sSASLUser;
std::shared_ptr<CAuthBase> m_spAuth;
SCString m_ssAcceptedCaps;
SCString m_ssSupportedTags;
// The capabilities supported by the ZNC core - capability names mapped
// to a pair which contains a bool describing whether the capability is
// server-dependent, and a capability value change handler.
std::map<CString, std::pair<bool, std::function<void(bool bVal)>>>
m_mCoreCaps;
// A subset of CIRCSock::GetAcceptedCaps(), the caps that can be listed
// in CAP LS and may be notified to the client with CAP NEW (cap-notify).
SCString m_ssServerDependentCaps;
SCString m_ssPreviouslyFailedSASLMechanisms;
// The capabilities supported by the ZNC core - capability names mapped to
// change handler. Note: this lists caps which don't require support on IRC
// server.
static const std::map<CString, std::function<void(CClient*, bool bVal)>>&
CoreCaps();
friend class ClientTest;
friend class CCoreCaps;
};
#endif // !ZNC_CLIENT_H
+16 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,10 +35,11 @@ struct CConfigEntry {
class CConfig {
public:
CConfig() : m_ConfigEntries(), m_SubConfigs() {}
CConfig() : m_ConfigEntries(), m_SubConfigs(), m_SubConfigNameSets() {}
typedef std::map<CString, VCString> EntryMap;
typedef std::map<CString, CConfigEntry> SubConfig;
typedef std::pair<CString, CConfigEntry> SubConfigEntry;
typedef std::vector<SubConfigEntry> SubConfig;
typedef std::map<CString, SubConfig> SubConfigMap;
typedef EntryMap::const_iterator EntryMapIterator;
@@ -62,14 +63,13 @@ class CConfig {
bool AddSubConfig(const CString& sTag, const CString& sName,
CConfig Config) {
SubConfig& conf = m_SubConfigs[sTag];
SubConfig::const_iterator it = conf.find(sName);
auto& nameset = m_SubConfigNameSets[sTag];
if (it != conf.end()) {
return false;
}
if (nameset.find(sName) != nameset.end()) return false;
nameset.insert(sName);
m_SubConfigs[sTag].emplace_back(sName, Config);
conf[sName] = Config;
return true;
}
@@ -142,9 +142,9 @@ class CConfig {
return false;
}
bool FindSubConfig(const CString& sName, SubConfig& Config,
bool FindSubConfig(const CString& sTag, SubConfig& Config,
bool bErase = true) {
SubConfigMap::iterator it = m_SubConfigs.find(sName);
auto it = m_SubConfigs.find(sTag);
if (it == m_SubConfigs.end()) {
Config.clear();
return false;
@@ -153,6 +153,7 @@ class CConfig {
if (bErase) {
m_SubConfigs.erase(it);
m_SubConfigNameSets.erase(sTag);
}
return true;
@@ -166,8 +167,12 @@ class CConfig {
void Write(CFile& file, unsigned int iIndentation = 0);
private:
typedef SCString SubConfigNameSet;
typedef std::map<CString, SubConfigNameSet> SubConfigNameSetMap;
EntryMap m_ConfigEntries;
SubConfigMap m_SubConfigs;
SubConfigNameSetMap m_SubConfigNameSets;
};
#endif // !ZNC_CONFIG_H
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+8 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ class CIRCNetworkPingTimer;
class CIRCNetworkJoinTimer;
class CMessage;
class CIRCNetwork {
class CIRCNetwork : private CCoreTranslationMixin {
public:
static bool IsValidNetwork(const CString& sNetwork);
@@ -93,6 +93,9 @@ class CIRCNetwork {
bool AddChan(CChan* pChan);
bool AddChan(const CString& sName, bool bInConfig);
bool DelChan(const CString& sName);
bool MoveChan(const CString& sChan, unsigned int index, CString& sError);
bool SwapChans(const CString& sChan1, const CString& sChan2,
CString& sError);
void JoinChans();
void JoinChans(std::set<CChan*>& sChans);
@@ -153,8 +156,11 @@ class CIRCNetwork {
void IRCConnected();
void IRCDisconnected();
void CheckIRCConnect();
void NotifyClientsAboutServerDependentCap(const CString& sCap, bool bValue);
bool IsServerCapAccepted(const CString& sCap) const;
bool PutIRC(const CString& sLine);
bool PutIRC(const CMessage& Message);
// Buffers
void AddRawBuffer(const CMessage& Format, const CString& sText = "") {
+73 -13
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,8 +56,49 @@ class CIRCSock : public CIRCSocket {
void SockError(int iErrno, const CString& sDescription) override;
void Timeout() override;
void ReachedMaxBuffer() override;
#ifdef HAVE_LIBSSL
void SSLCertError(X509* pCert) override;
#endif
/** Sends a raw data line to the server.
* @param sLine The line to be sent.
*
* The line is first passed \e unmodified to the \ref
* CModule::OnSendToIRC() module hook. If no module halts the process,
* the line is then sent to the server.
*
* Prefer \l PutIRC() instead.
*/
void PutIRCRaw(const CString& sLine);
/** Sends a message to the server.
* See \l PutIRC(const CMessage&) for details.
*/
void PutIRC(const CString& sLine);
/** Sends a message to the server.
* @param Message The message to be sent.
* @note Only known and compatible messages and tags are sent.
*
* This method can delay the delivery of the message to honor protection
* from flood.
*
* This method ensures that only tags, that were negotiated with CAP REQ
* and CAP ACK, are sent. Not all IRC server are capable of handling all
* messages and tags. Thus, in order to stay compatible with a variety of
* IRC servers, ZNC has to filter out messages and tags that the server
* has not explicitly acknowleged.
*
* Additional tags can be added via \l CIRCSock::SetTagSupport().
*
* @warning Bypassing the filter may cause troubles to some older IRC
* servers.
*
* It is possible to bypass the filter by converting a message to a string
* using \l CMessage::ToString(), and passing the resulting raw line to the
* \l CIRCSock::PutIRCRaw(const CString& sLine):
* \code
* pServer->PutIRCRaw(Message.ToString());
* \endcode
*/
void PutIRC(const CMessage& Message);
void PutIRCQuick(const CString& sLine); //!< Should be used for PONG only
void ResetChans();
void Quit(const CString& sQuitMsg = "");
@@ -71,6 +112,16 @@ class CIRCSock : public CIRCSocket {
* should be resumed again.
*/
void ResumeCap();
bool IsTagEnabled(const CString& sTag) const {
return 1 == m_ssSupportedTags.count(sTag);
}
/** Registers a tag as being supported or unsupported by the server.
* This doesn't affect tags which the server sends.
* @param sTag The tag to register.
* @param bState Whether the client supports the tag.
*/
void SetTagSupport(const CString& sTag, bool bState);
// Setters
void SetPass(const CString& s) { m_sPass = s; }
@@ -78,10 +129,11 @@ class CIRCSock : public CIRCSocket {
// Getters
unsigned int GetMaxNickLen() const { return m_uMaxNickLen; }
EChanModeArgs GetModeType(unsigned char uMode) const;
unsigned char GetPermFromMode(unsigned char uMode) const;
const std::map<unsigned char, EChanModeArgs>& GetChanModes() const {
return m_mueChanModes;
EChanModeArgs GetModeType(char cMode) const;
char GetPermFromMode(char cMode) const;
char GetModeFromPerm(char cPerm) const;
const std::map<char, EChanModeArgs>& GetChanModes() const {
return m_mceChanModes;
}
bool IsPermChar(const char c) const {
return (c != '\0' && GetPerms().find(c) != CString::npos);
@@ -101,15 +153,16 @@ class CIRCSock : public CIRCSocket {
bool HasAccountNotify() const { return m_bAccountNotify; }
bool HasExtendedJoin() const { return m_bExtendedJoin; }
bool HasServerTime() const { return m_bServerTime; }
const std::set<unsigned char>& GetUserModes() const {
return m_scUserModes;
}
bool HasMessageTagCap() const { return m_bMessageTagCap; }
const std::set<char>& GetUserModes() const { return m_scUserModes; }
// This is true if we are past raw 001
bool IsAuthed() const { return m_bAuthed; }
const SCString& GetAcceptedCaps() const { return m_ssAcceptedCaps; }
bool IsCapAccepted(const CString& sCap) {
return 1 == m_ssAcceptedCaps.count(sCap);
}
CString GetCapLsValue(const CString& sKey,
const CString& sDefault = "") const;
const MCString& GetISupport() const { return m_mISupport; }
CString GetISupport(const CString& sKey,
const CString& sDefault = "") const;
@@ -124,6 +177,7 @@ class CIRCSock : public CIRCSocket {
bool OnActionMessage(CActionMessage& Message);
bool OnAwayMessage(CMessage& Message);
bool OnCapabilityMessage(CMessage& Message);
bool OnChgHostMessage(CChgHostMessage& Message);
bool OnCTCPMessage(CCTCPMessage& Message);
bool OnErrorMessage(CMessage& Message);
bool OnInviteMessage(CMessage& Message);
@@ -137,10 +191,11 @@ class CIRCSock : public CIRCSocket {
bool OnPingMessage(CMessage& Message);
bool OnPongMessage(CMessage& Message);
bool OnQuitMessage(CQuitMessage& Message);
bool OnTagMessage(CTargetMessage& Message);
bool OnTextMessage(CTextMessage& Message);
bool OnTopicMessage(CTopicMessage& Message);
bool OnWallopsMessage(CMessage& Message);
bool OnServerCapAvailable(const CString& sCap);
bool OnServerCapAvailable(const CString& sCap, const CString& sValue);
// !Message Handlers
void SetNick(const CString& sNick);
@@ -158,10 +213,11 @@ class CIRCSock : public CIRCSocket {
bool m_bAccountNotify;
bool m_bExtendedJoin;
bool m_bServerTime;
bool m_bMessageTagCap;
CString m_sPerms;
CString m_sPermModes;
std::set<unsigned char> m_scUserModes;
std::map<unsigned char, EChanModeArgs> m_mueChanModes;
std::set<char> m_scUserModes;
std::map<char, EChanModeArgs> m_mceChanModes;
CIRCNetwork* m_pNetwork;
CNick m_Nick;
CString m_sPass;
@@ -170,18 +226,22 @@ class CIRCSock : public CIRCSocket {
unsigned int m_uCapPaused;
SCString m_ssAcceptedCaps;
SCString m_ssPendingCaps;
MCString m_msCapLsValues;
time_t m_lastCTCP;
unsigned int m_uNumCTCP;
static const time_t m_uCTCPFloodTime;
static const unsigned int m_uCTCPFloodCount;
MCString m_mISupport;
std::deque<CString> m_vsSendQueue;
std::deque<CMessage> m_vSendQueue;
short int m_iSendsAllowed;
unsigned short int m_uFloodBurst;
double m_fFloodRate;
bool m_bFloodProtection;
SCString m_ssSupportedTags;
VCString m_vsSSLError;
friend class CIRCFloodTimer;
friend class CCoreCaps;
};
#endif // !ZNC_IRCSOCK_H
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+67 -19
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,17 +17,10 @@
#ifndef ZNC_MESSAGE_H
#define ZNC_MESSAGE_H
// Remove this after Feb 2016 when Debian 7 is EOL
#if __cpp_ref_qualifiers >= 200710
#define ZNC_LVREFQUAL &
#elif defined(__clang__)
#define ZNC_LVREFQUAL &
#elif __GNUC__ > 4 || \
__GNUC__ == 4 && (__GNUC_MINOR__ > 8 || \
__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ >= 1)
#define ZNC_LVREFQUAL &
#ifdef SWIG
#define ZNC_MSG_DEPRECATED(msg)
#else
#define ZNC_LVREFQUAL
#define ZNC_MSG_DEPRECATED(msg) __attribute__((deprecated(msg)))
#endif
#include <znc/zncconfig.h>
@@ -55,7 +48,8 @@ class CIRCNetwork;
* - `nick` is the sender, which can be obtained with GetNick()
* - `cmd` is command, which is obtained via GetCommand()
* - `0`, `1`, ... are parameters, available via GetParam(n), which removes the
* leading colon (:). If you don't want to remove the colon, use GetParams().
* leading colon (:). If you don't want to remove the colon, use
* GetParamsColon().
*
* For certain events, like a PRIVMSG, convienience commands like GetChan() and
* GetNick() are available, this is not true for all CMessage extensions.
@@ -71,8 +65,10 @@ class CMessage {
Unknown,
Account,
Action,
Authenticate,
Away,
Capability,
ChgHost,
CTCP,
Error,
Invite,
@@ -86,6 +82,7 @@ class CMessage {
Ping,
Pong,
Quit,
TagMsg,
Text,
Topic,
Wallops,
@@ -114,8 +111,27 @@ class CMessage {
void SetCommand(const CString& sCommand);
const VCString& GetParams() const { return m_vsParams; }
CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const;
/**
* Get a subset of the message parameters
*
* This allows accessing a vector of a specific range of parameters,
* allowing easy inline use, such as `pChan->SetModes(Message.GetParam(2), Message.GetParamsSplit(3));`
*
* @param uIdx The index of the first parameter to retrieve
* @param uLen How many parameters to retrieve
* @return A VCString containing the retrieved parameters
*/
VCString GetParamsSplit(unsigned int uIdx, unsigned int uLen = -1) const;
void SetParams(const VCString& vsParams);
void SetParams(VCString&& vsParams);
/// @deprecated use GetParamsColon() instead.
CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const
ZNC_MSG_DEPRECATED("Use GetParamsColon() instead") {
return GetParamsColon(uIdx, uLen);
}
CString GetParamsColon(unsigned int uIdx, unsigned int uLen = -1) const;
CString GetParam(unsigned int uIdx) const;
void SetParam(unsigned int uIdx, const CString& sParam);
@@ -124,6 +140,7 @@ class CMessage {
void SetTime(const timeval& ts) { m_time = ts; }
const MCString& GetTags() const { return m_mssTags; }
MCString& GetTags() { return m_mssTags; }
void SetTags(const MCString& mssTags) { m_mssTags = mssTags; }
CString GetTag(const CString& sKey) const;
@@ -136,12 +153,12 @@ class CMessage {
};
CString ToString(unsigned int uFlags = IncludeAll) const;
void Parse(CString sMessage);
void Parse(const CString& sMessage);
// Implicit and explicit conversion to a subclass reference.
#ifndef SWIG
template <typename M>
M& As() ZNC_LVREFQUAL {
M& As() & {
static_assert(std::is_base_of<CMessage, M>{},
"Must be subclass of CMessage");
static_assert(sizeof(M) == sizeof(CMessage),
@@ -150,7 +167,7 @@ class CMessage {
}
template <typename M>
const M& As() const ZNC_LVREFQUAL {
const M& As() const& {
static_assert(std::is_base_of<CMessage, M>{},
"Must be subclass of CMessage");
static_assert(sizeof(M) == sizeof(CMessage),
@@ -160,12 +177,12 @@ class CMessage {
template <typename M, typename = typename std::enable_if<
std::is_base_of<CMessage, M>{}>::type>
operator M&() ZNC_LVREFQUAL {
operator M&() & {
return As<M>();
}
template <typename M, typename = typename std::enable_if<
std::is_base_of<CMessage, M>{}>::type>
operator const M&() const ZNC_LVREFQUAL {
operator const M&() const& {
return As<M>();
}
// REGISTER_ZNC_MESSAGE allows SWIG to instantiate correct .As<> calls.
@@ -225,6 +242,13 @@ class CActionMessage : public CTargetMessage {
};
REGISTER_ZNC_MESSAGE(CActionMessage);
class CAuthenticateMessage : public CMessage {
public:
CString GetText() const { return GetParam(0); }
void SetText(const CString& sText) { SetParam(0, sText); }
};
REGISTER_ZNC_MESSAGE(CAuthenticateMessage);
class CCTCPMessage : public CTargetMessage {
public:
bool IsReply() const { return GetCommand().Equals("NOTICE"); }
@@ -244,7 +268,14 @@ REGISTER_ZNC_MESSAGE(CJoinMessage);
class CModeMessage : public CTargetMessage {
public:
CString GetModes() const { return GetParams(1).TrimPrefix_n(":"); }
/// @deprecated Use GetModeList() and GetModeParams()
CString GetModes() const { return GetParamsColon(1).TrimPrefix_n(":"); }
CString GetModeList() const { return GetParam(1); };
VCString GetModeParams() const { return GetParamsSplit(2); };
bool HasModes() const { return !GetModeList().empty(); };
};
REGISTER_ZNC_MESSAGE(CModeMessage);
@@ -275,6 +306,8 @@ class CKickMessage : public CTargetMessage {
void SetKickedNick(const CString& sNick) { SetParam(1, sNick); }
CString GetReason() const { return GetParam(2); }
void SetReason(const CString& sReason) { SetParam(2, sReason); }
CString GetText() const { return GetReason(); }
void SetText(const CString& sText) { SetReason(sText); }
};
REGISTER_ZNC_MESSAGE(CKickMessage);
@@ -282,6 +315,8 @@ class CPartMessage : public CTargetMessage {
public:
CString GetReason() const { return GetParam(1); }
void SetReason(const CString& sReason) { SetParam(1, sReason); }
CString GetText() const { return GetReason(); }
void SetText(const CString& sText) { SetReason(sText); }
};
REGISTER_ZNC_MESSAGE(CPartMessage);
@@ -289,6 +324,8 @@ class CQuitMessage : public CMessage {
public:
CString GetReason() const { return GetParam(0); }
void SetReason(const CString& sReason) { SetParam(0, sReason); }
CString GetText() const { return GetReason(); }
void SetText(const CString& sText) { SetReason(sText); }
};
REGISTER_ZNC_MESSAGE(CQuitMessage);
@@ -303,7 +340,18 @@ class CTopicMessage : public CTargetMessage {
public:
CString GetTopic() const { return GetParam(1); }
void SetTopic(const CString& sTopic) { SetParam(1, sTopic); }
CString GetText() const { return GetTopic(); }
void SetText(const CString& sText) { SetTopic(sText); }
};
REGISTER_ZNC_MESSAGE(CTopicMessage);
class CChgHostMessage : public CMessage {
public:
CString GetNewIdent() const { return GetParam(0); }
void SetNewIdent(const CString& sIdent) { SetParam(0, sIdent); }
CString GetNewHost() const { return GetParam(1); }
void SetNewHost(const CString& sHost) { SetParam(1, sHost); }
};
REGISTER_ZNC_MESSAGE(CChgHostMessage);
#endif // !ZNC_MESSAGE_H
+170 -7
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
#include <znc/main.h>
#include <znc/Translation.h>
#include <functional>
#include <memory>
#include <set>
#include <queue>
#include <sys/time.h>
@@ -166,6 +167,19 @@ class CFPTimer;
class CSockManager;
// !Forward Declarations
class CCapability {
public:
virtual ~CCapability() = default;
virtual void OnServerChangedSupport(CIRCNetwork* pNetwork, bool bState) {}
virtual void OnClientChangedSupport(CClient* pClient, bool bState) {}
CModule* GetModule() { return m_pModule; }
void SetModule(CModule* p) { m_pModule = p; }
protected:
CModule* m_pModule = nullptr;
};
class CTimer : public CCron {
public:
CTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles,
@@ -335,7 +349,7 @@ CModule* TModLoad(ModHandle p, CUser* pUser, CIRCNetwork* pNetwork,
}
/** A helper class for handling commands in modules. */
class CModCommand {
class CModCommand : private CCoreTranslationMixin {
public:
/// Type for the callback function that handles the actual command.
typedef void (CModule::*ModCmdFunc)(const CString& sLine);
@@ -575,16 +589,21 @@ class CModule {
* @param pOpNick The nick who sent the mode change, or nullptr if set by server.
* @param Nick The nick whose channel mode changes.
* @param Channel The channel on which the user mode is changed.
* @param uMode The mode character that is changed, e.g. '@' for op.
* @param cMode The mode character that is changed, e.g. '@' for op.
* @param bAdded True if the mode is added, else false.
* @param bNoChange true if this mode change doesn't change anything
* because the nick already had this permission.
* @see CIRCSock::GetModeType() for converting uMode into a mode (e.g.
* 'o' for op).
*/
virtual void OnChanPermission3(const CNick* pOpNick, const CNick& Nick,
CChan& Channel, char cMode,
bool bAdded, bool bNoChange);
/// @deprecated. Use OnChanPermission3.
virtual void OnChanPermission2(const CNick* pOpNick, const CNick& Nick,
CChan& Channel, unsigned char uMode,
bool bAdded, bool bNoChange);
/// @deprecated. Use OnChanPermission3.
virtual void OnChanPermission(const CNick& OpNick, const CNick& Nick,
CChan& Channel, unsigned char uMode,
bool bAdded, bool bNoChange);
@@ -800,7 +819,6 @@ class CModule {
/** This module hook is called when a client sends a raw traffic line to ZNC.
* @param sLine The raw traffic line sent.
* @note The line does not include message tags. Use OnUserRawMessage() to access them.
* @return See CModule::EModRet.
*/
virtual EModRet OnUserRaw(CString& sLine);
@@ -994,13 +1012,28 @@ class CModule {
virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic);
/** Called for every CAP received via CAP LS from server.
* If you need to also advertise the cap to clients, use
* AddServerDependentCapability() instead.
* @param sCap capability supported by server.
* @return true if your module supports this CAP and
* needs to turn it on with CAP REQ.
*/
virtual bool OnServerCapAvailable(const CString& sCap);
/** Called for every CAP received via CAP LS from server.
* By default just calls OnServerCapAvailable() without sValue, so
* overriding one of the two is enough.
* If you need to also advertise the cap to clients, use
* AddServerDependentCapability() instead.
* @param sCap capability name supported by server.
* @param sValue value.
* @return true if your module supports this CAP and
* needs to turn it on with CAP REQ.
*/
virtual bool OnServerCap302Available(const CString& sCap, const CString& sValue);
/** Called for every CAP accepted or rejected by server
* (with CAP ACK or CAP NAK after our CAP REQ).
* If you need to also advertise the cap to clients, use
* AddServerDependentCapability() instead.
* @param sCap capability accepted/rejected by server.
* @param bSuccess true if capability was accepted, false if rejected.
*/
@@ -1046,14 +1079,39 @@ class CModule {
/// @deprecated Use OnSendToIRCMessage() instead.
virtual EModRet OnSendToIRC(CString& sLine);
/** This module hook is called when a user sends a TAGMSG message.
* @since 1.10.0
* @param Message The message which was sent.
* @return See CModule::EModRet.
*/
virtual EModRet OnUserTagMessage(CTargetMessage& Message);
/** Called when we receive a channel TAGMSG message <em>from IRC</em>.
* @since 1.10.0
* @param Message The channel message.
* @return See CModule::EModRet.
*/
virtual EModRet OnChanTagMessage(CTargetMessage& Message);
/** Called when we receive a private TAGMSG message <em>from IRC</em>.
* @since 1.10.0
* @param Message The message.
* @return See CModule::EModRet.
*/
virtual EModRet OnPrivTagMessage(CTargetMessage& Message);
ModHandle GetDLL() { return m_pDLL; }
/** This function sends a given raw IRC line to the IRC server, if we
/** This function sends a given IRC line to the IRC server, if we
* are connected to one. Else this line is discarded.
* @param sLine The line which should be sent.
* @return true if the line was queued for sending.
*/
virtual bool PutIRC(const CString& sLine);
/** This function sends a given IRC message to the IRC server, if we
* are connected to one. Else this message is discarded.
* @param Message The message which should be sent.
* @return true if the message was queued for sending.
*/
virtual bool PutIRC(const CMessage& Message);
/** This function sends a given raw IRC line to a client.
* If we are in a module hook which is called for a specific client,
* only that client will get the line, else all connected clients will
@@ -1273,8 +1331,32 @@ class CModule {
virtual EModRet OnUnknownUserRaw(CClient* pClient, CString& sLine);
virtual EModRet OnUnknownUserRawMessage(CMessage& Message);
/** Called after login, and also during JumpNetwork. */
virtual void OnClientAttached();
/** Called upon disconnect, and also during JumpNetwork. */
virtual void OnClientDetached();
#ifndef SWIG
/** Simple API to support client capabilities which depend on server to support that capability.
* It is built on top of other CAP related API, but removes boilerplate,
* and handles some tricky cases related to cap-notify and JumpNetwork. To
* use, create a subclass of CCapability, and pass to this function; it
* will automatically set the module pointer, then call the callbacks to
* notify you when server and client accepted support of the capability, or
* stopped supporting it. Note that it's not a strict toggle: e.g.
* sometimes client will disable the cap even when it was already disabled
* for that client.
* For perl and python modules, this function accepts 3 parameters:
* name, server callback, client callback; signatures of the callbacks are
* the same as of the virtual functions you'd implement in C++.
*/
void AddServerDependentCapability(const CString& sName, std::unique_ptr<CCapability> pCap);
#endif
/** Called when a client told us CAP LS. Use ssCaps.insert("cap-name")
* for announcing capabilities which your module supports.
* If you need to adverite the cap to clients only when it's also supported
* by the server, use AddServerDependentCapability() instead.
* @param pClient The client which requested the list.
* @param ssCaps set of caps which will be sent to client.
*/
@@ -1288,6 +1370,8 @@ class CModule {
virtual bool IsClientCapSupported(CClient* pClient, const CString& sCap,
bool bState);
/** Called when we actually need to turn a capability on or off for a client.
* If you need to adverite the cap to clients only when it's also supported
* by the server, use AddServerDependentCapability() instead.
* If implementing a custom capability, make sure to call
* pClient->SetTagSupport("tag-name", bState) for each tag that the
* capability provides.
@@ -1299,6 +1383,47 @@ class CModule {
virtual void OnClientCapRequest(CClient* pClient, const CString& sCap,
bool bState);
/** Called when a client requests SASL authentication. Use ssMechanisms.insert("MECHANISM")
* for announcing SASL mechanisms which your module supports.
* @param ssMechanisms The set of supported SASL mechanisms to append to.
* @since 1.10.0
*/
virtual void OnClientGetSASLMechanisms(SCString& ssMechanisms);
/** Called when a client has selected a SASL mechanism for SASL authentication.
* If implementing a SASL authentication mechanism, set sResponse to
* specify an initial challenge message to send to the client. Otherwise, an
* empty response will be sent. To avoid sending any immediate response,
* return HALT; in that case the module should schedule calling
* GetClient()->SendSASLChallenge() with the initial response: in IRC SASL,
* server always responds first.
* @param sMechanism The SASL mechanism selected by the client.
* @param sResponse The optional value of an initial SASL challenge message
* to send to the client.
* @since 1.10.0
*/
virtual EModRet OnClientSASLServerInitialChallenge(
const CString& sMechanism, CString& sResponse);
/** Called when a client is sending us a SASL message after the mechanism was selected.
* If implementing a SASL authentication mechanism, check the passed
* credentials, then either request more data by sending a challenge in
* GetClient()->SendSASLChallenge(), or reject authentication by calling
* GetClient()->RefuseSASLLogin(), or accept it by calling
* GetClient()->AcceptSASLLogin().
* At some point before accepting the login, you should call
* GetClient()->ParseUser(authz-id) to let it know the network name to
* attach to and the client id.
* @param sMechanism The SASL mechanism selected by the client.
* @param sMessage The SASL opaque value/credentials sent by the client,
* after debase64ing and concatenating if it was split.
* @since 1.10.0
*/
virtual EModRet OnClientSASLAuthenticate(const CString& sMechanism,
const CString& sMessage);
/** Called when a client sent '*' to abort SASL, or aborted it for another reason.
* @since 1.10.0
*/
virtual void OnClientSASLAborted();
/** Called when a module is going to be loaded.
* @param sModName name of the module.
* @param eType wanted type of the module (user/global).
@@ -1349,6 +1474,26 @@ class CModule {
const CString& sContext = "") const;
#endif
// Default implementations of several callbacks to make
// AddServerDependentCapability work in modpython/modperl.
// Don't worry about existence of these functions.
bool InternalServerDependentCapsOnServerCap302Available(
const CString& sCap, const CString& sValue);
void InternalServerDependentCapsOnServerCapResult(const CString& sCap,
bool bSuccess);
void InternalServerDependentCapsOnClientCapLs(CClient* pClient,
SCString& ssCaps);
bool InternalServerDependentCapsIsClientCapSupported(CClient* pClient,
const CString& sCap,
bool bState);
void InternalServerDependentCapsOnClientCapRequest(CClient* pClient,
const CString& sCap,
bool bState);
void InternalServerDependentCapsOnClientAttached();
void InternalServerDependentCapsOnClientDetached();
void InternalServerDependentCapsOnIRCConnected();
void InternalServerDependentCapsOnIRCDisconnected();
protected:
CModInfo::EModuleType m_eType;
CString m_sDescription;
@@ -1368,6 +1513,7 @@ class CModule {
CString m_sArgs;
CString m_sModPath;
CTranslationDomainRefHolder m_Translation;
std::map<CString, std::unique_ptr<CCapability>> m_mServerDependentCaps;
private:
MCString
@@ -1376,7 +1522,7 @@ class CModule {
std::map<CString, CModCommand> m_mCommands;
};
class CModules : public std::vector<CModule*> {
class CModules : public std::vector<CModule*>, private CCoreTranslationMixin {
public:
CModules();
~CModules();
@@ -1404,6 +1550,9 @@ class CModules : public std::vector<CModule*> {
CString& sRealName);
bool OnBroadcast(CString& sMessage);
bool OnChanPermission3(const CNick* pOpNick, const CNick& Nick,
CChan& Channel, char cMode, bool bAdded,
bool bNoChange);
bool OnChanPermission2(const CNick* pOpNick, const CNick& Nick,
CChan& Channel, unsigned char uMode, bool bAdded,
bool bNoChange);
@@ -1498,6 +1647,9 @@ class CModules : public std::vector<CModule*> {
bool OnUserTopicRequest(CString& sChannel);
bool OnUserQuit(CString& sMessage);
bool OnUserQuitMessage(CQuitMessage& Message);
bool OnUserTagMessage(CTargetMessage& Message);
bool OnChanTagMessage(CTargetMessage& Message);
bool OnPrivTagMessage(CTargetMessage& Message);
bool OnCTCPReply(CNick& Nick, CString& sMessage);
bool OnCTCPReplyMessage(CCTCPMessage& Message);
@@ -1528,8 +1680,10 @@ class CModules : public std::vector<CModule*> {
bool OnSendToClientMessage(CMessage& Message);
bool OnSendToIRC(CString& sLine);
bool OnSendToIRCMessage(CMessage& Message);
bool OnClientAttached();
bool OnClientDetached();
bool OnServerCapAvailable(const CString& sCap);
bool OnServerCapAvailable(const CString& sCap, const CString& sValue);
bool OnServerCapResult(const CString& sCap, bool bSuccess);
CModule* FindModule(const CString& sModule) const;
@@ -1574,6 +1728,14 @@ class CModules : public std::vector<CModule*> {
bool IsClientCapSupported(CClient* pClient, const CString& sCap,
bool bState);
bool OnClientCapRequest(CClient* pClient, const CString& sCap, bool bState);
bool OnClientGetSASLMechanisms(SCString& ssMechanisms);
bool OnClientSASLAborted();
bool OnClientSASLServerInitialChallenge(const CString& sMechanism,
CString& sResponse);
bool OnClientSASLAuthenticate(const CString& sMechanism,
const CString& sBuffer);
bool OnModuleLoading(const CString& sModName, const CString& sArgs,
CModInfo::EModuleType eType, bool& bSuccess,
CString& sRetMsg);
@@ -1587,6 +1749,7 @@ class CModules : public std::vector<CModule*> {
private:
static ModHandle OpenModule(const CString& sModule, const CString& sModPath,
CModInfo& Info, CString& sRetMsg);
static bool ValidateModuleName(const CString& sModule, CString& sRetMsg);
protected:
CUser* m_pUser;
+10 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,14 +47,19 @@ class CNick {
void SetNick(const CString& s);
void SetIdent(const CString& s);
void SetHost(const CString& s);
bool AddPerm(unsigned char uPerm);
bool RemPerm(unsigned char uPerm);
/// e.g. '@' for chanop.
bool AddPerm(char cPerm);
/// e.g. '@' for chanop.
bool RemPerm(char cPerm);
// !Setters
// Getters
/// e.g. '@' for chanop.
CString GetPermStr() const;
unsigned char GetPermChar() const;
bool HasPerm(unsigned char uPerm) const;
/// e.g. '@' for chanop.
char GetPermChar() const;
/// e.g. '@' for chanop.
bool HasPerm(char cPerm) const;
const CString& GetNick() const;
const CString& GetIdent() const;
const CString& GetHost() const;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+9 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
class CModule;
class CZNCSock : public Csock, public CCoreTranslationMixin {
class CZNCSock : public Csock, protected CCoreTranslationMixin {
public:
CZNCSock(int timeout = 60);
CZNCSock(const CString& sHost, u_short port, int timeout = 60);
@@ -36,12 +36,16 @@ class CZNCSock : public Csock, public CCoreTranslationMixin {
int VerifyPeerCertificate(int iPreVerify,
X509_STORE_CTX* pStoreCTX) override;
void SSLHandShakeFinished() override;
bool CheckSSLCert(X509* pCert);
virtual void SSLCertError(X509* pCert) {}
bool SNIConfigureClient(CString& sHostname) override;
CString GetSSLPeerFingerprint(X509* pCert = nullptr) const;
#else
CString GetSSLPeerFingerprint() const { return ""; }
#endif
void SetHostToVerifySSL(const CString& sHost) {
m_sHostToVerifySSL = sHost;
}
CString GetSSLPeerFingerprint() const;
void SetSSLTrustedPeerFingerprints(const SCString& ssFPs) {
m_ssTrustedFingerprints = ssFPs;
}
@@ -72,7 +76,8 @@ class CZNCSock : public Csock, public CCoreTranslationMixin {
enum EAddrType { ADDR_IPV4ONLY, ADDR_IPV6ONLY, ADDR_ALL };
class CSockManager : public TSocketManager<CZNCSock> {
class CSockManager : public TSocketManager<CZNCSock>,
private CCoreTranslationMixin {
public:
CSockManager();
virtual ~CSockManager();
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+9 -10
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
#include <znc/ZNCString.h>
#include <unordered_map>
#include <variant>
struct CTranslationInfo {
static std::map<CString, CTranslationInfo> GetTranslations();
@@ -83,20 +84,18 @@ class CDelayedTranslation {
class COptionalTranslation {
public:
COptionalTranslation(const CString& sText)
: m_bTranslating(false), m_sText(sText) {}
COptionalTranslation(const CString& sText) : m_text(sText) {}
COptionalTranslation(const char* s) : COptionalTranslation(CString(s)) {}
COptionalTranslation(const CDelayedTranslation& dTranslation)
: m_bTranslating(true), m_dTranslation(dTranslation) {}
COptionalTranslation(const CDelayedTranslation& dTranslation) : m_text(dTranslation) {}
CString Resolve() const {
return m_bTranslating ? m_dTranslation.Resolve() : m_sText;
if (m_text.index() == 0) {
return std::get<0>(m_text);
}
return std::get<1>(m_text).Resolve();
}
private:
bool m_bTranslating;
// TODO switch to std::variant<CString, CDelayedTranslation> after C++17
CString m_sText;
CDelayedTranslation m_dTranslation;
std::variant<CString, CDelayedTranslation> m_text;
};
// Used by everything except modules.
+47 -15
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
#include <znc/Utils.h>
#include <znc/Buffer.h>
#include <znc/Nick.h>
#include <znc/Translation.h>
#include <set>
#include <vector>
@@ -34,9 +35,9 @@ class CIRCSock;
class CUserTimer;
class CServer;
class CUser {
class CUser : private CCoreTranslationMixin {
public:
CUser(const CString& sUserName);
CUser(const CString& sUsername);
~CUser();
CUser(const CUser&) = delete;
@@ -44,31 +45,38 @@ class CUser {
bool ParseConfig(CConfig* Config, CString& sError);
// TODO refactor this
enum eHashType {
HASH_NONE,
HASH_MD5,
HASH_SHA256,
HASH_ARGON2ID,
HASH_DEFAULT = HASH_SHA256
// This should be kept in sync with CUtils::SaltedHash
#if ZNC_HAVE_ARGON
HASH_DEFAULT = HASH_ARGON2ID,
#else
HASH_DEFAULT = HASH_SHA256,
#endif
};
// If you change the default hash here and in HASH_DEFAULT,
// don't forget CUtils::sDefaultHash!
// TODO refactor this
static CString SaltedHash(const CString& sPass, const CString& sSalt) {
return CUtils::SaltedSHA256Hash(sPass, sSalt);
return CUtils::SaltedHash(sPass, sSalt);
}
CConfig ToConfig() const;
bool CheckPass(const CString& sPass) const;
/** Checks password, may upgrade the hash method. */
bool CheckPass(const CString& sPass);
bool AddAllowedHost(const CString& sHostMask);
bool RemAllowedHost(const CString& sHostMask);
void ClearAllowedHosts();
bool IsHostAllowed(const CString& sHost) const;
bool IsValid(CString& sErrMsg, bool bSkipPass = false) const;
static bool IsValidUserName(const CString& sUserName);
static CString MakeCleanUserName(const CString& sUserName);
static bool IsValidUsername(const CString& sUsername);
/** @deprecated Use IsValidUsername() instead. */
static bool IsValidUserName(const CString& sUsername);
static CString MakeCleanUsername(const CString& sUsername);
/** @deprecated Use MakeCleanUsername() instead. */
static CString MakeCleanUserName(const CString& sUsername);
// Modules
CModules& GetModules() { return *m_pModules; }
@@ -88,7 +96,10 @@ class CUser {
bool PutUser(const CString& sLine, CClient* pClient = nullptr,
CClient* pSkipClient = nullptr);
bool PutAllUser(const CString& sLine, CClient* pClient = nullptr,
CClient* pSkipClient = nullptr);
CClient* pSkipClient = nullptr)
ZNC_MSG_DEPRECATED("Use PutUser() instead") {
return PutUser(sLine, pClient, pSkipClient);
}
bool PutStatus(const CString& sLine, CClient* pClient = nullptr,
CClient* pSkipClient = nullptr);
bool PutStatusNotice(const CString& sLine, CClient* pClient = nullptr,
@@ -110,6 +121,7 @@ class CUser {
CString AddTimestamp(const CString& sStr) const;
CString AddTimestamp(time_t tm, const CString& sStr) const;
CString AddTimestamp(timeval tv, const CString& sStr) const;
void CloneNetworks(const CUser& User);
bool Clone(const CUser& User, CString& sErrorRet,
@@ -131,6 +143,11 @@ class CUser {
void SetDenyLoadMod(bool b);
void SetAdmin(bool b);
void SetDenySetBindHost(bool b);
void SetDenySetIdent(bool b);
void SetDenySetNetwork(bool b);
void SetDenySetRealName(bool b);
void SetDenySetQuitMsg(bool b);
void SetDenySetCTCPReplies(bool b);
bool SetStatusPrefix(const CString& s);
void SetDefaultChanModes(const CString& s);
void SetClientEncoding(const CString& s);
@@ -149,6 +166,7 @@ class CUser {
void SetTimestampFormat(const CString& s) { m_sTimestampFormat = s; }
void SetTimestampAppend(bool b) { m_bAppendTimestamp = b; }
void SetTimestampPrepend(bool b) { m_bPrependTimestamp = b; }
void SetAuthOnlyViaModule(bool b) { m_bAuthOnlyViaModule = b; }
void SetTimezone(const CString& s) { m_sTimezone = s; }
void SetJoinTries(unsigned int i) { m_uMaxJoinTries = i; }
void SetMaxJoins(unsigned int i) { m_uMaxJoins = i; }
@@ -161,7 +179,9 @@ class CUser {
// Getters
const std::vector<CClient*>& GetUserClients() const { return m_vClients; }
std::vector<CClient*> GetAllClients() const;
/** @deprecated Use GetUsername() instead. */
const CString& GetUserName() const;
const CString& GetUsername() const;
const CString& GetCleanUserName() const;
const CString& GetNick(bool bAllowDefault = true) const;
const CString& GetAltNick(bool bAllowDefault = true) const;
@@ -183,7 +203,13 @@ class CUser {
bool DenyLoadMod() const;
bool IsAdmin() const;
bool DenySetBindHost() const;
bool DenySetIdent() const;
bool DenySetNetwork() const;
bool DenySetRealName() const;
bool DenySetQuitMsg() const;
bool DenySetCTCPReplies() const;
bool MultiClients() const;
bool AuthOnlyViaModule() const;
const CString& GetStatusPrefix() const;
const CString& GetDefaultChanModes() const;
/** How long must an IRC connection be idle before ZNC sends a ping */
@@ -216,8 +242,8 @@ class CUser {
// !Getters
protected:
const CString m_sUserName;
const CString m_sCleanUserName;
const CString m_sUsername;
const CString m_sCleanUsername;
CString m_sNick;
CString m_sAltNick;
CString m_sIdent;
@@ -244,11 +270,17 @@ class CUser {
bool m_bDenyLoadMod;
bool m_bAdmin;
bool m_bDenySetBindHost;
bool m_bDenySetIdent;
bool m_bDenySetNetwork;
bool m_bDenySetRealName;
bool m_bDenySetQuitMsg;
bool m_bDenySetCTCPReplies;
bool m_bAutoClearChanBuffer;
bool m_bAutoClearQueryBuffer;
bool m_bBeingDeleted;
bool m_bAppendTimestamp;
bool m_bPrependTimestamp;
bool m_bAuthOnlyViaModule;
CUserTimer* m_pUserTimer;
+51 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,6 +44,7 @@ class CUtils {
static CString GetIP(unsigned long addr);
static unsigned long GetLongIP(const CString& sIP);
static CString GetHostName();
static void PrintError(const CString& sMessage);
static void PrintMessage(const CString& sMessage, bool bStrong = false);
@@ -51,15 +52,16 @@ class CUtils {
static void PrintAction(const CString& sMessage);
static void PrintStatus(bool bSuccess, const CString& sMessage = "");
#ifndef SWIGPERL
// TODO refactor this
static const CString sDefaultHash;
#endif
/** Asks password from stdin, with confirmation.
*
* @returns Piece of znc.conf with <Pass> block
* */
static CString AskSaltedHashPassForConfig();
static CString GetSaltedHashPass(CString& sSalt);
static CString GetSalt();
static CString SaltedMD5Hash(const CString& sPass, const CString& sSalt);
static CString SaltedSHA256Hash(const CString& sPass, const CString& sSalt);
static CString SaltedHash(const CString& sPass, const CString& sSalt);
static CString GetPass(const CString& sPrompt);
static bool GetInput(const CString& sPrompt, CString& sRet,
const CString& sDefault = "",
@@ -73,12 +75,27 @@ class CUtils {
static timeval GetTime();
static unsigned long long GetMillTime();
#ifdef HAVE_LIBSSL
static void GenerateCert(FILE* pOut, const CString& sHost = "");
static void GenerateCert(FILE* pOut);
#endif /* HAVE_LIBSSL */
static CString CTime(time_t t, const CString& sTZ);
static CString FormatTime(time_t t, const CString& sFormat,
const CString& sTZ);
/** Supports an additional format specifier for formatting sub-second values:
*
* - %f - sub-second fraction
* - %3f - millisecond (default, if no width is specified)
* - %6f - microsecond
*
* However, note that timeval only supports microsecond precision
* (thus, formatting with higher-than-microsecond precision will
* always result in trailing zeroes), and IRC server-time is specified
* in millisecond precision (thus formatting received timestamps with
* higher-than-millisecond precision will always result in trailing
* zeroes).
*/
static CString FormatTime(const timeval& tv, const CString& sFormat,
const CString& sTZ);
static CString FormatServerTime(const timeval& tv);
static timeval ParseServerTime(const CString& sTime);
static SCString GetTimezones();
@@ -113,7 +130,7 @@ class CException {
};
/** Generate a grid-like output from a given input.
/** Generate a grid-like or list-like output from a given input.
*
* @code
* CTable table;
@@ -137,9 +154,25 @@ class CException {
+-------+-------+
| hello | world |
+-------+-------+@endverbatim
*
* If the table has at most two columns, one can switch to ListStyle output
* like so:
* @code
* CTable table;
* table.AddColumn("a");
* table.AddColumn("b");
* table.SetStyle(CTable::ListStyle);
* // ...
* @endcode
*
* This will yield the following (Note that the header is omitted; asterisks
* denote bold text):
* @verbatim
*hello*: world@endverbatim
*/
class CTable : protected std::vector<std::vector<CString>> {
public:
enum EStyle { GridStyle, ListStyle };
CTable() {}
virtual ~CTable() {}
@@ -147,10 +180,18 @@ class CTable : protected std::vector<std::vector<CString>> {
* Please note that you should add all columns before starting to fill
* the table!
* @param sName The name of the column.
* @return false if a column by that name already existed.
* @return false if a column by that name already existed or the current
* style does not allow this many columns.
*/
bool AddColumn(const CString& sName);
/** Selects the output style of the table.
* Select between different styles for printing. Default is GridStyle.
* @param eNewStyle Table style type.
* @return false if the style cannot be applied (usually too many columns).
*/
bool SetStyle(EStyle eNewStyle);
/** Adds a new row to the table.
* After calling this you can fill the row with content.
* @return The index of this row
@@ -198,6 +239,7 @@ class CTable : protected std::vector<std::vector<CString>> {
std::vector<CString> m_vsHeaders;
// Used to cache the width of a column
std::map<CString, CString::size_type> m_msuWidths;
EStyle eStyle = GridStyle;
};
#ifdef HAVE_LIBSSL
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+8 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -697,4 +697,11 @@ class CInlineFormatMessage {
CString m_sFormat;
};
// For gtest
#ifdef GTEST_FAIL
inline void PrintTo(const CString& s, std::ostream* os) {
*os << '"' << s.Escape_n(CString::EDEBUG) << '"';
}
#endif
#endif // !ZNCSTRING_H
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+9 -12
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,19 +16,9 @@ limitations under the License.
#ifndef ZNC_VERSION_H
#define ZNC_VERSION_H
#ifndef BUILD_WITH_CMAKE
// The following defines are for #if comparison (preprocessor only likes ints)
#define VERSION_MAJOR 1
#define VERSION_MINOR 7
#define VERSION_PATCH -1
// This one is for display purpose and to check ABI compatibility of modules
#define VERSION_STR "1.7.x"
#endif
// Don't use this one
#define VERSION (VERSION_MAJOR + VERSION_MINOR / 10.0)
// autoconf: You can add -DVERSION_EXTRA="stuff" to your CXXFLAGS!
// CMake: You can add -DVERSION_EXTRA=stuff to cmake!
#ifndef VERSION_EXTRA
#define VERSION_EXTRA ""
@@ -67,9 +57,16 @@ extern const char* ZNC_VERSION_EXTRA;
#define ZNC_VERSION_TEXT_I18N "no"
#endif
// This is only here because HASH_DEFAULT has different value
#ifdef ZNC_HAVE_ARGON
#define ZNC_VERSION_TEXT_ARGON "yes"
#else
#define ZNC_VERSION_TEXT_ARGON "no"
#endif
#define ZNC_COMPILE_OPTIONS_STRING \
"IPv6: " ZNC_VERSION_TEXT_IPV6 ", SSL: " ZNC_VERSION_TEXT_SSL \
", DNS: " ZNC_VERSION_TEXT_DNS ", charset: " ZNC_VERSION_TEXT_ICU \
", i18n: " ZNC_VERSION_TEXT_I18N
", i18n: " ZNC_VERSION_TEXT_I18N ", Argon2: " ZNC_VERSION_TEXT_ARGON
#endif // !ZNC_VERSION_H
+7 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ class CConfigWriteTimer;
class CConfig;
class CFile;
class CZNC {
class CZNC : private CCoreTranslationMixin {
public:
CZNC();
~CZNC();
@@ -123,6 +123,7 @@ class CZNC {
}
void SetProtectWebSessions(bool b) { m_bProtectWebSessions = b; }
void SetHideVersion(bool b) { m_bHideVersion = b; }
void SetAuthOnlyViaModule(bool b) { m_bAuthOnlyViaModule = b; }
void SetConnectDelay(unsigned int i);
void SetSSLCiphers(const CString& sCiphers) { m_sSSLCiphers = sCiphers; }
bool SetSSLProtocols(const CString& sProtocols);
@@ -166,6 +167,7 @@ class CZNC {
unsigned int GetConnectDelay() const { return m_uiConnectDelay; }
bool GetProtectWebSessions() const { return m_bProtectWebSessions; }
bool GetHideVersion() const { return m_bHideVersion; }
bool GetAuthOnlyViaModule() const { return m_bAuthOnlyViaModule; }
CString GetSSLCiphers() const { return m_sSSLCiphers; }
CString GetSSLProtocols() const { return m_sSSLProtocols; }
Csock::EDisableProtocol GetDisabledSSLProtocols() const {
@@ -261,6 +263,8 @@ class CZNC {
static void DumpConfig(const CConfig* Config);
private:
static CString FormatBindError();
CFile* InitPidFile();
bool ReadConfig(CConfig& config, CString& sError);
@@ -315,6 +319,7 @@ class CZNC {
TCacheMap<CString> m_sConnectThrottle;
bool m_bProtectWebSessions;
bool m_bHideVersion;
bool m_bAuthOnlyViaModule;
CTranslationDomainRefHolder m_Translation;
unsigned int m_uiConfigWriteDelay;
CConfigWriteTimer* m_pConfigTimer;
+5 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,9 +31,11 @@
#define HAVE_PTHREAD 1
#cmakedefine HAVE_THREADED_DNS 1
#cmakedefine HAVE_LIBSSL 1
#cmakedefine HAVE_SSL_SESSION_get0_cipher 1
#cmakedefine HAVE_IPV6 1
#cmakedefine HAVE_ZLIB 1
#cmakedefine HAVE_I18N 1
#cmakedefine ZNC_HAVE_ARGON 1
#cmakedefine CSOCK_USE_POLL 1
#cmakedefine HAVE_GETOPT_LONG 1
@@ -41,6 +43,8 @@
#cmakedefine HAVE_TCSETATTR 1
#cmakedefine HAVE_GETPASSPHRASE 1
#cmakedefine HAVE_CLOCK_GETTIME 1
#cmakedefine ZNC_HAVE_GETHOSTNAME 1
#cmakedefine ZNC_HAVE_UNAME 1
#cmakedefine HAVE_ICU 1
#define U_USING_ICU_NAMESPACE 1
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

-210
View File
@@ -1,210 +0,0 @@
dnl @synopsis AC_PROG_SWIG([major.minor.micro])
dnl
dnl NOTICE: for new code, use http://www.gnu.org/s/autoconf-archive/ax_pkg_swig.html instead.
dnl
dnl This macro searches for a SWIG installation on your system. If
dnl found you should call SWIG via $(SWIG). You can use the optional
dnl first argument to check if the version of the available SWIG is
dnl greater than or equal to the value of the argument. It should have
dnl the format: N[.N[.N]] (N is a number between 0 and 999. Only the
dnl first N is mandatory.)
dnl
dnl If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks
dnl that the swig package is this version number or higher.
dnl
dnl In configure.in, use as:
dnl
dnl AC_PROG_SWIG(1.3.17)
dnl SWIG_ENABLE_CXX
dnl SWIG_MULTI_MODULE_SUPPORT
dnl SWIG_PYTHON
dnl
dnl @category InstalledPackages
dnl @author Sebastian Huber <sebastian-huber@web.de>
dnl @author Alan W. Irwin <irwin@beluga.phys.uvic.ca>
dnl @author Rafael Laboissiere <rafael@laboissiere.net>
dnl @author Andrew Collier <abcollier@yahoo.com>
dnl @version 2004-09-20
dnl
dnl Modified by Alexey Sokolov <alexey@asokolov.org> on 2012-08-08
dnl @license GPLWithACException
dnl
dnl NOTICE: for new code, use http://www.gnu.org/s/autoconf-archive/ax_pkg_swig.html instead.
AC_DEFUN([AC_PROG_SWIG],[
SWIG_ERROR=""
if test -n "$1"; then
# Calculate the required version number components
[required=$1]
[required_major=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_major" ; then
[required_major=0]
fi
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required_minor=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_minor" ; then
[required_minor=0]
fi
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required_patch=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_patch" ; then
[required_patch=0]
fi
fi
# for "python 3 abc set" and "PyInt_FromSize_t in python3" checks
cat <<-END > conftest-python.i
%module conftest;
%include <pyabc.i>
%include <std_set.i>
%template(SInt) std::set<int>;
END
# check if perl has std::...::size_type defined. Don't add new tests to this .i; it'll break this test due to check for "NewPointerObj(("
cat <<-END > conftest-perl.i
%module conftest;
%include <std_vector.i>
%include <std_list.i>
%include <std_deque.i>
%template() std::vector<int>;
%template() std::list<int>;
%template() std::deque<int>;
std::vector<int>::size_type checkVector();
std::list<int>::size_type checkList();
std::deque<int>::size_type checkDeque();
END
SWIG_installed_versions=""
AC_CACHE_CHECK([for SWIG >= $1], [znc_cv_path_SWIG], [
AC_PATH_PROGS_FEATURE_CHECK([SWIG], [swig swig2.0 swig3.0], [
echo trying $ac_path_SWIG >&AS_MESSAGE_LOG_FD
$ac_path_SWIG -version >&AS_MESSAGE_LOG_FD
[swig_version=`$ac_path_SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
if test -n "$swig_version"; then
swig_right_version=1
SWIG_installed_versions="$SWIG_installed_versions $swig_version "
if test -n "$required"; then
# Calculate the available version number components
[available=$swig_version]
[available_major=`echo $available | sed 's/[^0-9].*//'`]
if test -z "$available_major" ; then
[available_major=0]
fi
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
[available_minor=`echo $available | sed 's/[^0-9].*//'`]
if test -z "$available_minor" ; then
[available_minor=0]
fi
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
[available_patch=`echo $available | sed 's/[^0-9].*//'`]
if test -z "$available_patch" ; then
[available_patch=0]
fi
if test $available_major -lt $required_major; then
swig_right_version=0
elif test $available_major -eq $required_major; then
if test $available_minor -lt $required_minor; then
swig_right_version=0
elif test $available_minor -eq $required_minor; then
if test $available_patch -lt $required_patch; then
swig_right_version=0
fi
fi
fi
fi
if test $swig_right_version -eq 1; then
# "python 3 abc set", "PyInt_FromSize_t in python3" and "perl size_type" checks
echo "checking behavior of this SWIG" >&AS_MESSAGE_LOG_FD
$ac_path_SWIG -python -py3 -c++ -shadow conftest-python.i >&AS_MESSAGE_LOG_FD && \
echo "python wrapper created" >&AS_MESSAGE_LOG_FD && \
echo "testing std::set... ">&AS_MESSAGE_LOG_FD && \
grep SInt_discard conftest.py > /dev/null 2>&1 && \
echo "std::set works" >&AS_MESSAGE_LOG_FD && \
echo "testing PyInt_FromSize_t..." >&AS_MESSAGE_LOG_FD && \
grep '#define PyInt_FromSize_t' conftest-python_wrap.cxx > /dev/null 2>&1 && \
echo "PyInt_FromSize_t is defined" >&AS_MESSAGE_LOG_FD && \
$ac_path_SWIG -perl -c++ -shadow conftest-perl.i >&AS_MESSAGE_LOG_FD && \
echo "perl wrapper created" >&AS_MESSAGE_LOG_FD && \
echo "testing size_type..." >&AS_MESSAGE_LOG_FD && \
test 0 -eq `grep -c 'NewPointerObj((' conftest-perl_wrap.cxx` && \
echo "size_type work" >&AS_MESSAGE_LOG_FD && \
znc_cv_path_SWIG=$ac_path_SWIG \
ac_path_SWIG_found=:
if test "x$ac_path_SWIG_found" != "x:"; then
echo "fail" >&AS_MESSAGE_LOG_FD
fi
rm -f conftest-python_wrap.cxx conftest.py
rm -f conftest-perl_wrap.cxx conftest.pm
else
echo "SWIG version >= $1 is required. You have '$swig_version'" >&AS_MESSAGE_LOG_FD
fi
fi
echo end trying $ac_path_SWIG >&AS_MESSAGE_LOG_FD
])
])
rm -f conftest-python.i conftest-perl.i
if test -n "$SWIG_installed_versions"; then
AC_MSG_NOTICE([Following SWIG versions are found:$SWIG_installed_versions])
fi
AC_SUBST([SWIG], [$znc_cv_path_SWIG])
if test -n "$SWIG"; then
SWIG_LIB=`$SWIG -swiglib`
fi
AC_SUBST([SWIG_LIB])
])
# SWIG_ENABLE_CXX()
#
# Enable SWIG C++ support. This affects all invocations of $(SWIG).
AC_DEFUN([SWIG_ENABLE_CXX],[
AC_REQUIRE([AC_PROG_SWIG])
AC_REQUIRE([AC_PROG_CXX])
SWIG="$SWIG -c++"
])
# SWIG_MULTI_MODULE_SUPPORT()
#
# Enable support for multiple modules. This effects all invocations
# of $(SWIG). You have to link all generated modules against the
# appropriate SWIG runtime library. If you want to build Python
# modules for example, use the SWIG_PYTHON() macro and link the
# modules against $(SWIG_PYTHON_LIBS).
#
AC_DEFUN([SWIG_MULTI_MODULE_SUPPORT],[
AC_REQUIRE([AC_PROG_SWIG])
SWIG="$SWIG -noruntime"
])
# SWIG_PYTHON([use-shadow-classes = {no, yes}])
#
# Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS),
# and $(SWIG_PYTHON_OPT) output variables.
#
# $(SWIG_PYTHON_OPT) contains all necessary SWIG options to generate
# code for Python. Shadow classes are enabled unless the value of the
# optional first argument is exactly 'no'. If you need multi module
# support (provided by the SWIG_MULTI_MODULE_SUPPORT() macro) use
# $(SWIG_PYTHON_LIBS) to link against the appropriate library. It
# contains the SWIG Python runtime library that is needed by the type
# check system for example.
AC_DEFUN([SWIG_PYTHON],[
AC_REQUIRE([AC_PROG_SWIG])
AC_REQUIRE([AC_PYTHON_DEVEL])
test "x$1" != "xno" || swig_shadow=" -noproxy"
AC_SUBST([SWIG_PYTHON_OPT],[-python$swig_shadow])
AC_SUBST([SWIG_PYTHON_CPPFLAGS],[$PYTHON_CPPFLAGS])
])
-163
View File
@@ -1,163 +0,0 @@
# ============================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
# ============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++11
# standard; if necessary, add switches to CXXFLAGS to enable support.
#
# The first argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The second argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline C++11 support is required and that the macro
# should error out if no mode with that support is found. If specified
# 'optional', then configuration proceeds regardless, after defining
# HAVE_CXX11 if and only if a supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 5
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
struct Base {
virtual void f() {}
};
struct Child : public Base {
virtual void f() override {}
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);
auto d = a;
auto l = [](){};
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function because of this
namespace test_template_alias_sfinae {
struct foo {};
template<typename T>
using member = typename T::member_type;
template<typename T>
void func(...) {}
template<typename T>
void func(member<T>*) {}
void test();
void test() {
func<foo>(0);
}
}
]])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
m4_if([$1], [], [],
[$1], [ext], [],
[$1], [noext], [],
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
AC_LANG_PUSH([C++])dnl
ac_success=no
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
ax_cv_cxx_compile_cxx11,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[ax_cv_cxx_compile_cxx11=yes],
[ax_cv_cxx_compile_cxx11=no])])
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
ac_success=yes
fi
m4_if([$1], [noext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=gnu++11 -std=gnu++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
m4_if([$1], [ext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=c++11 -std=c++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx11_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
fi
else
if test x$ac_success = xno; then
HAVE_CXX11=0
AC_MSG_NOTICE([No compiler with C++11 support was found])
else
HAVE_CXX11=1
AC_DEFINE(HAVE_CXX11,1,
[define if the compiler supports basic C++11 syntax])
fi
AC_SUBST(HAVE_CXX11)
fi
])
-310
View File
@@ -1,310 +0,0 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
#
# DESCRIPTION
#
# This macro figures out how to build C programs using POSIX threads. It
# sets the PTHREAD_LIBS output variable to the threads library and linker
# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also link it with them as well. e.g. you should link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threads programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
# PTHREAD_CFLAGS.
#
# ACTION-IF-FOUND is a list of shell commands to run if a threads library
# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
# is not found. If ACTION-IF-FOUND is not specified, the default action
# will define HAVE_PTHREAD.
#
# Please let the authors know if this macro fails on any platform, or if
# you have any other suggestions or comments. This macro was based on work
# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
# Alejandro Forero Cuervo to the autoconf macro repository. We are also
# grateful for the helpful feedback of numerous users.
#
# Updated for Autoconf 2.68 by Daniel Richard G.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 17
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_PUSH([C++])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CXXFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
AC_MSG_RESULT($ax_pthread_ok)
if test x"$ax_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CXXFLAGS="$save_CXXFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
;;
*-darwin*)
ax_pthread_flags="-pthread $ax_pthread_flags"
;;
esac
if test x"$ax_pthread_ok" = xno; then
for flag in $ax_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
PTHREAD_LIBS="$flag"
;;
pthread-config)
AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
if test x"$ax_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CXXFLAGS="$CXXFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
static void routine(void *a) { *((int*)a) = 42; }
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
pthread_join(th, 0);
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
LIBS="$save_LIBS"
CXXFLAGS="$save_CXXFLAGS"
AC_MSG_RESULT($ax_pthread_ok)
if test "x$ax_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$ax_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $attr; return attr /* ; */])],
[attr_name=$attr; break],
[])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*-osf* | *-hpux*) flag="-D_REENTRANT";;
*solaris*)
if test "$GXX" = "yes"; then
flag="-D_REENTRANT"
else
flag="-mt -D_REENTRANT"
fi
;;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
ax_cv_PTHREAD_PRIO_INHERIT, [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT; (void) i;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
LIBS="$save_LIBS"
CXXFLAGS="$save_CXXFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GXX" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
fi
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$ax_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
ax_pthread_ok=no
$2
fi
AC_LANG_POP
])dnl AX_PTHREAD
-272
View File
@@ -1,272 +0,0 @@
# iconv.m4 serial 18 (gettext-0.18.2)
dnl Copyright (C) 2000-2002, 2007-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
[
dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
dnl AC_REQUIRE([AC_LIB_RPATH])
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
dnl accordingly.
AC_LIB_LINKFLAGS_BODY([iconv])
])
AC_DEFUN([AM_ICONV_LINK],
[
[HAVE_ICONV=""]
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
dnl those with the standalone portable GNU libiconv installed).
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
dnl accordingly.
AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
dnl Add $INCICONV to CPPFLAGS before performing the following checks,
dnl because if the user has installed libiconv and not disabled its use
dnl via --without-libiconv-prefix, he wants to use it. The first
dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed.
am_save_CPPFLAGS="$CPPFLAGS"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
am_cv_func_iconv="no, consider installing GNU libiconv"
am_cv_lib_iconv=no
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
]],
[[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);]])],
[am_cv_func_iconv=yes])
if test "$am_cv_func_iconv" != yes; then
am_save_LIBS="$LIBS"
LIBS="$LIBS $LIBICONV"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
]],
[[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);]])],
[am_cv_lib_iconv=yes]
[am_cv_func_iconv=yes])
LIBS="$am_save_LIBS"
fi
])
if test "$am_cv_func_iconv" = yes; then
AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
dnl Solaris 10.
am_save_LIBS="$LIBS"
if test $am_cv_lib_iconv = yes; then
LIBS="$LIBS $LIBICONV"
fi
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <iconv.h>
#include <string.h>
int main ()
{
int result = 0;
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
returns. */
{
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
if (cd_utf8_to_88591 != (iconv_t)(-1))
{
static const char input[] = "\342\202\254"; /* EURO SIGN */
char buf[10];
const char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_utf8_to_88591,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 1;
iconv_close (cd_utf8_to_88591);
}
}
/* Test against Solaris 10 bug: Failures are not distinguishable from
successful returns. */
{
iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
if (cd_ascii_to_88591 != (iconv_t)(-1))
{
static const char input[] = "\263";
char buf[10];
const char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_ascii_to_88591,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 2;
iconv_close (cd_ascii_to_88591);
}
}
/* Test against AIX 6.1..7.1 bug: Buffer overrun. */
{
iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
static const char input[] = "\304";
static char buf[2] = { (char)0xDE, (char)0xAD };
const char *inptr = input;
size_t inbytesleft = 1;
char *outptr = buf;
size_t outbytesleft = 1;
size_t res = iconv (cd_88591_to_utf8,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
result |= 4;
iconv_close (cd_88591_to_utf8);
}
}
#if 0 /* This bug could be worked around by the caller. */
/* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
{
iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
char buf[50];
const char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_88591_to_utf8,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if ((int)res > 0)
result |= 8;
iconv_close (cd_88591_to_utf8);
}
}
#endif
/* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
provided. */
if (/* Try standardized names. */
iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
/* Try IRIX, OSF/1 names. */
&& iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
/* Try AIX names. */
&& iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
/* Try HP-UX names. */
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
result |= 16;
return result;
}]])],
[am_cv_func_iconv_works=yes],
[am_cv_func_iconv_works=no],
[
changequote(,)dnl
case "$host_os" in
aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
*) am_cv_func_iconv_works="guessing yes" ;;
esac
changequote([,])dnl
])
LIBS="$am_save_LIBS"
])
case "$am_cv_func_iconv_works" in
*no) am_func_iconv=no am_cv_lib_iconv=no ;;
*) am_func_iconv=yes ;;
esac
else
am_func_iconv=no am_cv_lib_iconv=no
fi
if test "$am_func_iconv" = yes; then
AC_DEFINE([HAVE_ICONV], [1],
[Define if you have the iconv() function and it works.])
[HAVE_ICONV=1]
fi
if test "$am_cv_lib_iconv" = yes; then
AC_MSG_CHECKING([how to link with libiconv])
AC_MSG_RESULT([$LIBICONV])
else
dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
dnl either.
CPPFLAGS="$am_save_CPPFLAGS"
LIBICONV=
LTLIBICONV=
fi
AC_SUBST([HAVE_ICONV])
AC_SUBST([LIBICONV])
AC_SUBST([LTLIBICONV])
])
dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
dnl avoid warnings like
dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
dnl This is tricky because of the way 'aclocal' is implemented:
dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
dnl Otherwise aclocal's initial scan pass would miss the macro definition.
dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
dnl warnings.
m4_define([gl_iconv_AC_DEFUN],
m4_version_prereq([2.64],
[[AC_DEFUN_ONCE(
[$1], [$2])]],
[m4_ifdef([gl_00GNULIB],
[[AC_DEFUN_ONCE(
[$1], [$2])]],
[[AC_DEFUN(
[$1], [$2])]])]))
gl_iconv_AC_DEFUN([AM_ICONV],
[
AM_ICONV_LINK
if test "$am_cv_func_iconv" = yes; then
AC_MSG_CHECKING([for iconv declaration])
AC_CACHE_VAL([am_cv_proto_iconv], [
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
#else
size_t iconv();
#endif
]],
[[]])],
[am_cv_proto_iconv_arg1=""],
[am_cv_proto_iconv_arg1="const"])
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
AC_MSG_RESULT([
$am_cv_proto_iconv])
AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
[Define as const if the declaration of iconv() needs const.])
dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
m4_ifdef([gl_ICONV_H_DEFAULTS],
[AC_REQUIRE([gl_ICONV_H_DEFAULTS])
if test -n "$am_cv_proto_iconv_arg1"; then
ICONV_CONST="const"
fi
])
fi
])
-88
View File
@@ -1,88 +0,0 @@
# visibility.m4 serial 3 (gettext-0.18)
dnl Copyright (C) 2005, 2008-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
dnl Changes done by Uli Schlachter (C) 2011:
dnl - Renamed everything from gl_ to znc_
dnl - Instead of using CFLAGS, this now uses CXXFLAGS (the macro would actually
dnl silently break if you called AC_LANG with anything but C before it)
dnl - Because of the above, this now requiers AC_PROG_CXX and $GXX instead
dnl of $GCC
dnl - Added calls to AC_LANG_PUSH([C++]) and AC_LANG_POP
dnl - Replaced AC_TRY_COMPILE with AC_COMPILE_IFELSE
dnl - Added a definition for dummyfunc() so that this works with
dnl -Wmissing-declarations
dnl Tests whether the compiler supports the command-line option
dnl -fvisibility=hidden and the function and variable attributes
dnl __attribute__((__visibility__("hidden"))) and
dnl __attribute__((__visibility__("default"))).
dnl Does *not* test for __visibility__("protected") - which has tricky
dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on
dnl MacOS X.
dnl Does *not* test for __visibility__("internal") - which has processor
dnl dependent semantics.
dnl Does *not* test for #pragma GCC visibility push(hidden) - which is
dnl "really only recommended for legacy code".
dnl Set the variable CFLAG_VISIBILITY.
dnl Defines and sets the variable HAVE_VISIBILITY.
AC_DEFUN([ZNC_VISIBILITY],
[
AC_REQUIRE([AC_PROG_CXX])
AC_LANG_PUSH([C++])
CFLAG_VISIBILITY=
HAVE_VISIBILITY=0
if test -n "$GXX"; then
dnl First, check whether -Werror can be added to the command line, or
dnl whether it leads to an error because of some other option that the
dnl user has put into $CC $CFLAGS $CPPFLAGS.
AC_MSG_CHECKING([whether the -Werror option is usable])
AC_CACHE_VAL([znc_cv_cc_vis_werror], [
znc_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
[znc_cv_cc_vis_werror=yes],
[znc_cv_cc_vis_werror=no])
CXXFLAGS="$znc_save_CXXFLAGS"])
AC_MSG_RESULT([$znc_cv_cc_vis_werror])
dnl Now check whether visibility declarations are supported.
AC_MSG_CHECKING([for simple visibility declarations])
AC_CACHE_VAL([znc_cv_cc_visibility], [
znc_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
dnl We use the option -Werror and a function dummyfunc, because on some
dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning
dnl "visibility attribute not supported in this configuration; ignored"
dnl at the first function definition in every compilation unit, and we
dnl don't want to use the option in this case.
if test $znc_cv_cc_vis_werror = yes; then
CXXFLAGS="$CXXFLAGS -Werror"
fi
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
extern __attribute__((__visibility__("default"))) int exportedvar;
extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
extern __attribute__((__visibility__("default"))) int exportedfunc (void);
void dummyfunc (void);
void dummyfunc (void) {}]],
[])],
[znc_cv_cc_visibility=yes],
[znc_cv_cc_visibility=no])
CXXFLAGS="$znc_save_CXXFLAGS"])
AC_MSG_RESULT([$znc_cv_cc_visibility])
if test $znc_cv_cc_visibility = yes; then
CFLAG_VISIBILITY="-fvisibility=hidden"
HAVE_VISIBILITY=1
fi
fi
AC_SUBST([CFLAG_VISIBILITY])
AC_SUBST([HAVE_VISIBILITY])
AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY],
[Define to 1 or 0, depending whether the compiler supports simple visibility declarations.])
AC_LANG_POP
])
+9 -11
View File
@@ -16,6 +16,7 @@ if [ "x$1" = "x--nightly" ]; then
TARGZ=$3
SIGN=0
DESC=-nightly-`date +%Y%m%d`-`git $GITDIR rev-parse HEAD | cut -b-8`
NIGHTLY=1
else
VERSION=$1
if [ "x$VERSION" = "x" ] ; then
@@ -32,8 +33,8 @@ else
ZNCDIR=znc-$VERSION
TARGZ=$ZNCDIR.tar.gz
SIGN=1
DESC=""
# DESC="-rc1"
DESC="$(sed -En 's/set\(alpha_version "(.*)"\).*/\1/p' CMakeLists.txt)"
NIGHTLY=0
fi
TARGZ=`readlink -f -- $TARGZ`
@@ -42,6 +43,8 @@ echo "Exporting . to $TMPDIR/$ZNCDIR..."
git checkout-index --all --prefix=$TMPDIR/$ZNCDIR/
mkdir -p --mode=0755 $TMPDIR/$ZNCDIR/third_party/Csocket
cp -p third_party/Csocket/Csocket.cc third_party/Csocket/Csocket.h $TMPDIR/$ZNCDIR/third_party/Csocket/
mkdir -p --mode=0755 $TMPDIR/$ZNCDIR/third_party/cctz
cp -Rp third_party/cctz/src third_party/cctz/include third_party/cctz/LICENSE.txt $TMPDIR/$ZNCDIR/third_party/cctz/
(
cd $TMPDIR2
cmake $TMPDIR/$ZNCDIR -DWANT_PERL=yes -DWANT_PYTHON=yes
@@ -49,17 +52,12 @@ cp -p third_party/Csocket/Csocket.cc third_party/Csocket/Csocket.h $TMPDIR/$ZNCD
)
(
cd $TMPDIR/$ZNCDIR
AUTOMAKE_FLAGS="--add-missing --copy" ./autogen.sh
rm -r autom4te.cache/
rm .travis* .appveyor*
rm -rf .travis* .appveyor* .ci/ .github/
rm make-tarball.sh
# For autoconf
sed -e "s/THIS_IS_NOT_TARBALL//" -i Makefile.in
echo '#include <znc/version.h>' > src/version.cpp
echo "const char* ZNC_VERSION_EXTRA = VERSION_EXTRA \"$DESC\";" >> src/version.cpp
# For cmake
if [ "x$DESC" != "x" ]; then
echo $DESC > .nightly
if [ $NIGHTLY = 1 ]; then
echo $DESC > .nightly
fi
fi
)
(
-44
View File
@@ -1,44 +0,0 @@
SHELL := @SHELL@
# Support out-of-tree builds
VPATH := @srcdir@
prefix := @prefix@
exec_prefix := @exec_prefix@
datarootdir := @datarootdir@
mandir := @mandir@
INSTALL := @INSTALL@
INSTALL_DATA := @INSTALL_DATA@
MAN1 := znc.1.gz znc-buildmod.1.gz
ifneq "$(V)" ""
VERBOSE=1
endif
ifeq "$(VERBOSE)" ""
Q=@
E=@echo
else
Q=
E=@\#
endif
all: $(MAN1)
%.1.gz: %.1 Makefile
$(E) Packing man page $@...
$(Q)gzip -9 <$< >$@
clean:
-rm -f $(MAN1)
install: $(MAN1)
test -d $(DESTDIR)$(mandir)/man1 || $(INSTALL) -d $(DESTDIR)$(mandir)/man1
$(INSTALL_DATA) $(MAN1) $(DESTDIR)$(mandir)/man1
uninstall:
for file in $(MAN1) ; do \
rm $(DESTDIR)$(mandir)/man1/$$file || exit 1 ; \
done
rmdir $(DESTDIR)$(mandir)/man1
+11 -17
View File
@@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -24,8 +24,7 @@ function(add_cxx_module mod modpath)
PREFIX ""
SUFFIX ".so"
NO_SONAME true
CXX_VISIBILITY_PRESET "hidden"
COMPILE_DEFINITIONS "znc_export_lib_EXPORTS")
CXX_VISIBILITY_PRESET "hidden")
if(moddef_${mod})
target_compile_definitions("module_${mod}" ${moddef_${mod}})
endif()
@@ -38,11 +37,7 @@ function(add_cxx_module mod modpath)
if(moddepend_${mod})
add_dependencies("module_${mod}" ${moddepend_${mod}})
endif()
# ${znclib_LIB_DEPENDS} is to overcome OSX's need for -undefined suppress
# when accessing symbols exported by dependencies of znclib (e.g.
# openssl), but not used in znclib itself
target_link_libraries("module_${mod}" PRIVATE ${znc_link} ${modlink_${mod}}
${znclib_LIB_DEPENDS})
target_link_libraries("module_${mod}" PRIVATE ZNC ${modlink_${mod}})
set_target_properties("module_${mod}" PROPERTIES "" "" ${modprop_${mod}})
install(TARGETS "module_${mod}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/znc")
@@ -55,8 +50,7 @@ function(add_python_module mod modpath)
endfunction()
if(CYRUS_FOUND)
set(modcompile_cyrusauth PRIVATE ${CYRUS_CFLAGS})
set(modlink_cyrusauth ${CYRUS_LDFLAGS})
set(modlink_cyrusauth PkgConfig::CYRUS)
else()
set(moddisable_cyrusauth true)
endif()
@@ -67,7 +61,7 @@ else()
set(moddisable_modperl true)
endif()
if(PYTHON_FOUND)
if(Python3_FOUND)
add_subdirectory(modpython)
else()
set(moddisable_modpython true)
@@ -91,8 +85,6 @@ foreach(modpath ${all_modules})
continue()
endif()
list(APPEND actual_modules "${modpath}")
set(modenabled true)
if(moddisable_${mod})
@@ -110,14 +102,16 @@ foreach(modpath ${all_modules})
if(modenabled)
if(modtype STREQUAL "cpp")
add_cxx_module("${mod}" "${modpath}")
endif()
if(modtype STREQUAL "pm")
elseif(modtype STREQUAL "pm")
add_perl_module("${mod}" "${modpath}")
endif()
if(modtype STREQUAL "py")
elseif(modtype STREQUAL "py")
add_python_module("${mod}" "${modpath}")
else()
continue()
endif()
endif()
list(APPEND actual_modules "${modpath}")
endforeach()
if(HAVE_I18N)
-146
View File
@@ -1,146 +0,0 @@
#
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
all:
SHELL := @SHELL@
# Support out-of-tree builds
srcdir := @srcdir@
VPATH := @srcdir@
prefix := @prefix@
exec_prefix := @exec_prefix@
datarootdir := @datarootdir@
bindir := @bindir@
datadir := @datadir@
sysconfdir := @sysconfdir@
libdir := @libdir@
sbindir := @sbindir@
localstatedir := @localstatedir@
CXX := @CXX@
# CXXFLAGS are for the main binary, so don't use them here, use MODFLAGS instead
MODFLAGS := -I$(srcdir)/../include -I../include @CPPFLAGS@ @MODFLAGS@
MODLINK := @MODLINK@
LDFLAGS := @LDFLAGS@
ISCYGWIN := @ISCYGWIN@
# LIBS are not and should not be used in here.
# The znc binary links already against those.
# ...but not on cygwin!
LIBS :=
ifeq "$(ISCYGWIN)" "1"
LIBS += @LIBS@
endif
PERL_ON := @PERL@
PERL := @PERL_BINARY@
PYTHON_ON:= @PYTHON@
PY_CFLAGS:= @python_CFLAGS@
PY_LDFLAGS:=@python_LIBS@
SWIG := @SWIG@
MODDIR := @MODDIR@
DATADIR := @DATADIR@
LIBZNC := @LIBZNC@
LIBZNCDIR:= @LIBZNCDIR@
INSTALL := @INSTALL@
INSTALL_PROGRAM := @INSTALL_PROGRAM@
INSTALL_SCRIPT := @INSTALL_SCRIPT@
INSTALL_DATA := @INSTALL_DATA@
SED := @SED@
TCL_FLAGS:= @TCL_FLAGS@
ifneq "$(V)" ""
VERBOSE=1
endif
ifeq "$(VERBOSE)" ""
Q=@
E=@echo
C=-s
else
Q=
E=@\#
C=
endif
ifneq "$(LIBZNC)" ""
LIBS += -L.. -lznc -Wl,-rpath,$(LIBZNCDIR)
endif
CLEAN :=
FILES := $(notdir $(wildcard $(srcdir)/*.cpp))
include $(srcdir)/modperl/Makefile.inc
include $(srcdir)/modpython/Makefile.inc
include $(srcdir)/modtcl/Makefile.inc
FILES := $(basename $(FILES))
ifeq "@NOSSL@" "1"
FILES := $(foreach file, $(FILES), \
$(if $(shell grep REQUIRESSL $(srcdir)/$(file).cpp), \
, \
$(basename $(file)) \
))
endif
ifeq "@CYRUS@" ""
FILES := $(shell echo $(FILES) | sed -e "s:cyrusauth::")
endif
cyrusauthLDFLAGS := -lsasl2
TARGETS := $(addsuffix .so, $(sort $(FILES)))
CLEAN += *.so *.o
.PHONY: all clean install install_datadir uninstall
.SECONDARY:
all: $(TARGETS)
install: all install_datadir
$(INSTALL_PROGRAM) $(TARGETS) $(DESTDIR)$(MODDIR)
install_datadir:
rm -rf $(DESTDIR)$(DATADIR)/modules
test -d $(DESTDIR)$(MODDIR) || $(INSTALL) -d $(DESTDIR)$(MODDIR)
test -d $(DESTDIR)$(DATADIR)/modules || $(INSTALL) -d $(DESTDIR)$(DATADIR)/modules
rm -rf $(DESTDIR)$(MODDIR)/*.so
cp -R $(srcdir)/data/* $(DESTDIR)$(DATADIR)/modules
find $(DESTDIR)$(DATADIR)/modules -type d -exec chmod 0755 '{}' \;
find $(DESTDIR)$(DATADIR)/modules -type f -exec chmod 0644 '{}' \;
clean:
rm -rf $(CLEAN)
%.o: %.cpp Makefile
@mkdir -p .depend
$(E) Building module $(notdir $(basename $@))...
$(Q)$(CXX) $(MODFLAGS) -c -o $@ $< $($(notdir $(basename $@))CXXFLAGS) -MD -MF .depend/$(notdir $@).dep
%.so: %.o Makefile
$(E) "Linking module" $(notdir $(basename $@))...
$(Q)$(CXX) $(MODFLAGS) $(LDFLAGS) $(MODLINK) -o $@ $< $($(notdir $(basename $@))LDFLAGS) $(LIBS)
uninstall:
# Yes, we are lazy, just remove everything in there
rm -rf $(DESTDIR)$(MODDIR)/*
rm -rf $(DESTDIR)$(DATADIR)/*
rmdir $(DESTDIR)$(MODDIR)
rmdir $(DESTDIR)$(DATADIR)
-include $(wildcard .depend/*.dep)
+105
View File
@@ -0,0 +1,105 @@
/*
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <znc/FileUtils.h>
#include <znc/Server.h>
#include <znc/IRCNetwork.h>
#include <znc/User.h>
#include <znc/ZNCDebug.h>
class CAdminDebugMod : public CModule {
private:
CString m_sEnabledBy;
public:
MODCONSTRUCTOR(CAdminDebugMod) {
AddHelpCommand();
AddCommand("Enable", "", t_d("Enable Debug Mode"),
[=](const CString& sLine) { CommandEnable(sLine); });
AddCommand("Disable", "", t_d("Disable Debug Mode"),
[=](const CString& sLine) { CommandDisable(sLine); });
AddCommand("Status", "", t_d("Show the Debug Mode status"),
[=](const CString& sLine) { CommandStatus(sLine); });
}
void CommandEnable(const CString& sCommand) {
if (!GetUser()->IsAdmin()) {
PutModule(t_s("Access denied!"));
return;
}
ToggleDebug(true, GetUser()->GetNick());
}
void CommandDisable(const CString& sCommand) {
if (!GetUser()->IsAdmin()) {
PutModule(t_s("Access denied!"));
return;
}
ToggleDebug(false, m_sEnabledBy);
}
bool ToggleDebug(bool bEnable, const CString& sEnabledBy) {
if (!CDebug::StdoutIsTTY()) {
PutModule(t_s("Failure. We need to be running with a TTY. (is ZNC running with --foreground?)"));
return false;
}
bool bValue = CDebug::Debug();
if (bEnable == bValue) {
if (bEnable) {
PutModule(t_s("Already enabled."));
} else {
PutModule(t_s("Already disabled."));
}
return false;
}
CDebug::SetDebug(bEnable);
CString sEnabled = bEnable ? "on" : "off";
CZNC::Get().Broadcast(
"An administrator has just turned Debug Mode \02" + sEnabled +
"\02. It was enabled by \02" + sEnabledBy + "\02.");
if (bEnable) {
CZNC::Get().Broadcast(
"Messages, credentials, and other sensitive data may become "
"exposed to the host during this period.");
m_sEnabledBy = sEnabledBy;
} else {
m_sEnabledBy = "";
}
return true;
}
void CommandStatus(const CString& sCommand) {
if (CDebug::Debug()) {
PutModule(t_s("Debugging mode is \02on\02."));
} else {
PutModule(t_s("Debugging mode is \02off\02."));
}
PutModule(t_s("Logging to: \02stdout\02."));
}
};
template <>
void TModInfo<CAdminDebugMod>(CModInfo& Info) {
Info.SetWikiPage("admindebug");
}
GLOBALMODULEDEFS(CAdminDebugMod, t_s("Enable Debug mode dynamically."))
+9 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,39 +58,37 @@ class CAdminLogMod : public CModule {
}
void OnIRCConnected() override {
Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() +
Log("[" + GetUser()->GetUsername() + "/" + GetNetwork()->GetName() +
"] connected to IRC: " +
GetNetwork()->GetCurrentServer()->GetName());
}
void OnIRCDisconnected() override {
Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() +
Log("[" + GetUser()->GetUsername() + "/" + GetNetwork()->GetName() +
"] disconnected from IRC");
}
EModRet OnRaw(CString& sLine) override {
if (sLine.StartsWith("ERROR ")) {
EModRet OnRawMessage(CMessage& Message) override {
if (Message.GetCommand().Equals("ERROR")) {
// ERROR :Closing Link: nick[24.24.24.24] (Excess Flood)
// ERROR :Closing Link: nick[24.24.24.24] Killer (Local kill by
// Killer (reason))
CString sError(sLine.substr(6));
if (sError.Left(1) == ":") sError.LeftChomp();
Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() +
Log("[" + GetUser()->GetUsername() + "/" + GetNetwork()->GetName() +
"] disconnected from IRC: " +
GetNetwork()->GetCurrentServer()->GetName() + " [" +
sError + "]",
Message.GetParamsColon(0) + "]",
LOG_NOTICE);
}
return CONTINUE;
}
void OnClientLogin() override {
Log("[" + GetUser()->GetUserName() + "] connected to ZNC from " +
Log("[" + GetUser()->GetUsername() + "] connected to ZNC from " +
GetClient()->GetRemoteIP());
}
void OnClientDisconnect() override {
Log("[" + GetUser()->GetUserName() + "] disconnected from ZNC from " +
Log("[" + GetUser()->GetUsername() + "] disconnected from ZNC from " +
GetClient()->GetRemoteIP());
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+2 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -83,6 +83,7 @@ class CAutoCycleMod : public CModule {
void OnListCommand(const CString& sLine) {
CTable Table;
Table.AddColumn(t_s("Channel"));
Table.SetStyle(CTable::ListStyle);
for (const CString& sChan : m_vsChans) {
Table.AddRow();
+5 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -132,7 +132,8 @@ class CAutoOpUser {
bool FromString(const CString& sLine) {
m_sUsername = sLine.Token(0, false, "\t");
sLine.Token(1, false, "\t").Split(",", m_ssHostmasks);
// Trim because there was a bug which caused spaces in the hostname
sLine.Token(1, false, "\t").Trim_n().Split(",", m_ssHostmasks);
m_sUserKey = sLine.Token(2, false, "\t");
sLine.Token(3, false, "\t").Split(" ", m_ssChans);
@@ -374,7 +375,7 @@ class CAutoOpMod : public CModule {
void OnAddMasksCommand(const CString& sLine) {
CString sUser = sLine.Token(1);
CString sHostmasks = sLine.Token(2, true);
CString sHostmasks = sLine.Token(2);
if (sHostmasks.empty()) {
PutModule(t_s("Usage: AddMasks <user> <mask>,[mask] ..."));
@@ -395,7 +396,7 @@ class CAutoOpMod : public CModule {
void OnDelMasksCommand(const CString& sLine) {
CString sUser = sLine.Token(1);
CString sHostmasks = sLine.Token(2, true);
CString sHostmasks = sLine.Token(2);
if (sHostmasks.empty()) {
PutModule(t_s("Usage: DelMasks <user> <mask>,[mask] ..."));
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
* Copyright (C) 2008 Michael "Svedrin" Ziegler diese-addy@funzt-halt.net
*
* Licensed under the Apache License, Version 2.0 (the "License");
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

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