From 0819346192d8928beb0ae76c851b103001dae913 Mon Sep 17 00:00:00 2001 From: dnzbk Date: Mon, 12 Feb 2024 14:57:19 +0300 Subject: [PATCH 01/42] Refactor: extension unpack error messages --- daemon/extension/ExtensionManager.cpp | 14 +++++++------- webui/config.js | 2 +- webui/index.html | 6 ++++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/daemon/extension/ExtensionManager.cpp b/daemon/extension/ExtensionManager.cpp index 1fe0cad54..0d5c66ac0 100644 --- a/daemon/extension/ExtensionManager.cpp +++ b/daemon/extension/ExtensionManager.cpp @@ -111,16 +111,16 @@ namespace ExtensionManager }; unpacker.SetArgs(std::move(args)); - int res = unpacker.Execute(); + int code = unpacker.Execute(); - if (res != 0) + if (code < 0) { - if (!FileSystem::DeleteFile(filename.c_str())) - { - return "Failed to unpack and delete temp file: " + filename; - } + return "Failed to unpack " + filename + ". Make sure that path to 7-Zip is valid."; + } - return "Failed to unpack " + filename; + if (code > 0) + { + return "Failed to unpack " + filename + ". 7-Zip exit code: " + std::to_string(code); } if (!FileSystem::DeleteFile(filename.c_str())) diff --git a/webui/config.js b/webui/config.js index 5521c57fd..b83ad44ef 100644 --- a/webui/config.js +++ b/webui/config.js @@ -3354,7 +3354,7 @@ var ExtensionManager = (new function($) { hideLoadingBanner(); render(getAllExtensions()); - showErrorBanner("Failed to download extensions", error); + showErrorBanner("Failed to fetch the list of available extensions", error); } ); } diff --git a/webui/index.html b/webui/index.html index dc1925f9d..34a6315cd 100644 --- a/webui/index.html +++ b/webui/index.html @@ -718,6 +718,12 @@

list, it will be removed without the possibility of reinstalling it. +
+
+ NOTE: + Extension Manager requires 7zip to unpack downloaded extensions. + If you are having issues with Extension Manager downloads - please make sure that SevenZipCmd is valid. +


From 3dd7912b35ebb714ae10ada1f18953272e5b77a6 Mon Sep 17 00:00:00 2001 From: dnzbk Date: Mon, 12 Feb 2024 16:43:49 +0300 Subject: [PATCH 02/42] Add: 7zip exit codes decoder --- daemon/extension/ExtensionManager.cpp | 8 ++++---- daemon/postprocess/Unpack.cpp | 29 +++++++++++++++++++++++++++ daemon/postprocess/Unpack.h | 11 ++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/daemon/extension/ExtensionManager.cpp b/daemon/extension/ExtensionManager.cpp index 0d5c66ac0..6a574fffb 100644 --- a/daemon/extension/ExtensionManager.cpp +++ b/daemon/extension/ExtensionManager.cpp @@ -111,16 +111,16 @@ namespace ExtensionManager }; unpacker.SetArgs(std::move(args)); - int code = unpacker.Execute(); + int ec = unpacker.Execute(); - if (code < 0) + if (ec < 0) { return "Failed to unpack " + filename + ". Make sure that path to 7-Zip is valid."; } - if (code > 0) + if (ec > 0) { - return "Failed to unpack " + filename + ". 7-Zip exit code: " + std::to_string(code); + return "Failed to unpack " + filename + ". " + UnpackController::DecodeSevenZipExitCode(ec); } if (!FileSystem::DeleteFile(filename.c_str())) diff --git a/daemon/postprocess/Unpack.cpp b/daemon/postprocess/Unpack.cpp index b37065a4c..782ed526a 100644 --- a/daemon/postprocess/Unpack.cpp +++ b/daemon/postprocess/Unpack.cpp @@ -961,3 +961,32 @@ bool UnpackController::HasCompletedArchiveFiles(NzbInfo* nzbInfo) return false; } + +const char* UnpackController::DecodeSevenZipExitCode(int ec) +{ + // 7-Zip exit codes according to https://documentation.help/7-Zip/exit_codes.htm + switch (ec) + { + case SevenZipExitCodes::NoError: + return "No error"; + + case SevenZipExitCodes::Warning: + return "Warning (Non fatal error(s)). \ + For example, one or more files were locked by some other application, \ + so they were not compressed."; + + case SevenZipExitCodes::FatalError: + return "Fatal error"; + + case SevenZipExitCodes::CmdLineError: + return "Command line error"; + + case SevenZipExitCodes::NotEnoughMemoryError: + return "Not enough memory for operation"; + + case SevenZipExitCodes::CanceledByUser: + return "User stopped the process"; + + default: "Unknown 7-Zip error"; + }; +} diff --git a/daemon/postprocess/Unpack.h b/daemon/postprocess/Unpack.h index c44c903a7..560ddb927 100644 --- a/daemon/postprocess/Unpack.h +++ b/daemon/postprocess/Unpack.h @@ -33,6 +33,7 @@ class UnpackController : public Thread, public ScriptController virtual void Stop(); static void StartJob(PostInfo* postInfo); static bool HasCompletedArchiveFiles(NzbInfo* nzbInfo); + static const char* DecodeSevenZipExitCode(int ec); protected: virtual bool ReadLine(char* buf, int bufSize, FILE* stream); @@ -45,6 +46,16 @@ class UnpackController : public Thread, public ScriptController upSevenZip }; + enum SevenZipExitCodes + { + NoError = 0, + Warning = 1, + FatalError = 2, + CmdLineError = 7, + NotEnoughMemoryError = 8, + CanceledByUser = 255, + }; + typedef std::vector FileListBase; class FileList : public FileListBase { From 2de2c56a8deaa1bdbf86c573c6ae8d97fce4b1b7 Mon Sep 17 00:00:00 2001 From: dnzbk Date: Mon, 12 Feb 2024 16:46:44 +0300 Subject: [PATCH 03/42] Fix: error message --- daemon/extension/ExtensionManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/extension/ExtensionManager.cpp b/daemon/extension/ExtensionManager.cpp index 6a574fffb..4f0c088db 100644 --- a/daemon/extension/ExtensionManager.cpp +++ b/daemon/extension/ExtensionManager.cpp @@ -115,7 +115,7 @@ namespace ExtensionManager if (ec < 0) { - return "Failed to unpack " + filename + ". Make sure that path to 7-Zip is valid."; + return "Failed to unpack " + filename + ". Make sure that the path to 7-Zip is valid."; } if (ec > 0) From d5a88312e8d24beb9b1dca7cb232482b7e89116e Mon Sep 17 00:00:00 2001 From: dnzbk Date: Mon, 12 Feb 2024 16:52:33 +0300 Subject: [PATCH 04/42] Fix: NOTE text --- webui/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webui/index.html b/webui/index.html index 34a6315cd..f6511634c 100644 --- a/webui/index.html +++ b/webui/index.html @@ -721,8 +721,8 @@



NOTE: - Extension Manager requires 7zip to unpack downloaded extensions. - If you are having issues with Extension Manager downloads - please make sure that SevenZipCmd is valid. + Extension Manager requires 7-Zip to unpack downloaded extensions. + If you are having issues with installing extensions - please make sure that SevenZipCmd is valid.

From 7374ba4d42f219ea09c34375b1cbd01cd9118830 Mon Sep 17 00:00:00 2001 From: dnzbk Date: Tue, 13 Feb 2024 08:50:41 +0300 Subject: [PATCH 05/42] Fix: return default --- daemon/postprocess/Unpack.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/daemon/postprocess/Unpack.cpp b/daemon/postprocess/Unpack.cpp index 782ed526a..48093f3c8 100644 --- a/daemon/postprocess/Unpack.cpp +++ b/daemon/postprocess/Unpack.cpp @@ -987,6 +987,7 @@ const char* UnpackController::DecodeSevenZipExitCode(int ec) case SevenZipExitCodes::CanceledByUser: return "User stopped the process"; - default: "Unknown 7-Zip error"; + default: + return "Unknown 7-Zip error"; }; } From 18b69f8f1374a933dc44bdf0b0733ab39f4dfd7e Mon Sep 17 00:00:00 2001 From: dnzbk Date: Tue, 13 Feb 2024 10:32:34 +0300 Subject: [PATCH 06/42] Add: link to 'SevenZipCmd' --- webui/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webui/index.html b/webui/index.html index f6511634c..39b435138 100644 --- a/webui/index.html +++ b/webui/index.html @@ -722,7 +722,8 @@


NOTE: Extension Manager requires 7-Zip to unpack downloaded extensions. - If you are having issues with installing extensions - please make sure that SevenZipCmd is valid. + If you are having issues with Extension Manager downloads - please check + SevenZipCmd.

From 7f68f557d888b237fffd7cd8ea3231edf2fc7a15 Mon Sep 17 00:00:00 2001 From: phnzb <139914799+phnzb@users.noreply.github.com> Date: Wed, 14 Feb 2024 15:15:23 +0300 Subject: [PATCH 07/42] Docker fix for v23+ (remove copying default scripts) (#170) --- docker/entrypoint.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 8c143ce14..39c2f802c 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -25,13 +25,8 @@ if [ ! -z "${NZBGET_PASS}" ]; then OPTIONS="${OPTIONS}-o ControlPassword=${NZBGET_PASS} " fi -# copy default scripts if not exists +# create scripts dir mkdir -p /downloads/scripts -for SCRIPT in EMail.py Logger.py; do - if [ ! -f /downloads/scripts/$SCRIPT ]; then - cp /app/nzbget/share/nzbget/scripts/$SCRIPT /downloads/scripts/ - fi -done # change userid and groupid PUID=${PUID:-1000} From 800f371ed372125e1b5866b9d64dbd5d9dd6e371 Mon Sep 17 00:00:00 2001 From: phnzb <139914799+phnzb@users.noreply.github.com> Date: Thu, 15 Feb 2024 11:37:45 +0300 Subject: [PATCH 08/42] Change CI jobs labels (#171) --- .github/workflows/linux.yml | 2 +- .github/workflows/qnap-repack.yml | 2 +- .github/workflows/qnap.yml | 2 +- .github/workflows/synology.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9e618da22..21d9ca5d5 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -6,7 +6,7 @@ on: jobs: build: - runs-on: [self-hosted, linux] + runs-on: [self-hosted, nzbget-linux] steps: diff --git a/.github/workflows/qnap-repack.yml b/.github/workflows/qnap-repack.yml index a628e9fd2..091385628 100644 --- a/.github/workflows/qnap-repack.yml +++ b/.github/workflows/qnap-repack.yml @@ -16,7 +16,7 @@ jobs: if: ${{ inputs.external_call == false }} repack: - runs-on: [self-hosted, linux] + runs-on: [self-hosted, nzbget-qnap] needs: [build-linux] if: always() permissions: diff --git a/.github/workflows/qnap.yml b/.github/workflows/qnap.yml index 896794598..258fb7029 100644 --- a/.github/workflows/qnap.yml +++ b/.github/workflows/qnap.yml @@ -6,7 +6,7 @@ on: jobs: build: - runs-on: [self-hosted, linux] + runs-on: [self-hosted, nzbget-qnap] steps: diff --git a/.github/workflows/synology.yml b/.github/workflows/synology.yml index 78b98b08e..1f996f3f3 100644 --- a/.github/workflows/synology.yml +++ b/.github/workflows/synology.yml @@ -6,7 +6,7 @@ on: jobs: build: - runs-on: [self-hosted, linux] + runs-on: [self-hosted, nzbget-synology] steps: From 34f27444e8be0452f50f5678dab1106668968215 Mon Sep 17 00:00:00 2001 From: phnzb <139914799+phnzb@users.noreply.github.com> Date: Fri, 16 Feb 2024 11:49:20 +0300 Subject: [PATCH 09/42] RISC-V 64 Support (#172) --- .github/workflows/linux.yml | 7 ++++++- linux/installer.sh | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 21d9ca5d5..5e6e9989e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -29,7 +29,12 @@ jobs: rm -rf /build/output cp -r . /build/nzbget cd /build - docker run -e ALL_ARCHS="i686 x86_64 aarch64 armhf armel mipseb mipsel ppc6xx ppc500" -v /build:/build nzbget-build /build/scripts/build-nzbget-ci.sh + if [ "$GITHUB_REF_NAME" == "develop" ] || [ "$GITHUB_REF_NAME" == "main" ]; then + DEBUG=yes + else + DEBUG=no + fi + ALL_ARCHS="i686 x86_64 aarch64 armhf armel mipseb mipsel ppc6xx ppc500 riscv64" DEBUG=$DEBUG /build/scripts/build-nzbget-ci.sh - name: Rename build artifacts if: github.ref_name != 'main' && github.ref_name != 'develop' diff --git a/linux/installer.sh b/linux/installer.sh index fe08a18aa..55f78b716 100755 --- a/linux/installer.sh +++ b/linux/installer.sh @@ -97,6 +97,7 @@ PrintHelp() PrintArch "mipseb" " mipseb - MIPS (big endian)" PrintArch "ppc6xx" " ppc6xx - PowerPC 6xx (603e series)" PrintArch "ppc500" " ppc500 - PowerPC e500 (core e500v1/e500v2)" + PrintArch "riscv64" " riscv64 - RISC-V 64-bit" Info "" # Check if command 'basename' is available and fallback to full path if it's not @@ -198,6 +199,9 @@ DetectArch() ppc) ARCH=ppcx ;; + riscv64) + ARCH=riscv64 + ;; esac fi From 133aeb6a7788d96c13d1a55bc96a577a0c88b75a Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 16 Feb 2024 14:42:38 +0300 Subject: [PATCH 10/42] issue templates (#175) * issue templates * changed dropdown order for default values * PR review fixes --- .github/ISSUE_TEMPLATE/01_bug_report.yml | 85 +++++++++++++++++++ .github/ISSUE_TEMPLATE/02_feature_request.yml | 36 ++++++++ .github/ISSUE_TEMPLATE/03_build.yml | 71 ++++++++++++++++ .github/ISSUE_TEMPLATE/04_extension.yml | 25 ++++++ .github/ISSUE_TEMPLATE/config.yml | 8 ++ 5 files changed, 225 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/01_bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/02_feature_request.yml create mode 100644 .github/ISSUE_TEMPLATE/03_build.yml create mode 100644 .github/ISSUE_TEMPLATE/04_extension.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/01_bug_report.yml b/.github/ISSUE_TEMPLATE/01_bug_report.yml new file mode 100644 index 000000000..e9670e9de --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01_bug_report.yml @@ -0,0 +1,85 @@ +name: Bug Report +description: 'Any bug about core nzbget, EXCLUDING extensions, performance issues or compiling nzbget.' +labels: ['bug'] +body: +- type: checkboxes + attributes: + label: Is there already an issue for your problem? + description: Please make sure you are not creating an already submitted Issue. Check closed issues as well, because your issue may have already been fixed. + options: + - label: I have checked older issues, open and closed + required: true +- type: dropdown + attributes: + label: NZBGet Version + description: Which version of NZBGet has this bug? + options: + - v23-stable + - v23-testing + - v22-stable (nzbgetcom takeover) + - v22-testing (nzbgetcom takeover) + - v21 or earlier (orignal nzbget) + validations: + required: true +- type: dropdown + attributes: + label: Platform + description: Select a specific platform for this bug report, choose All if it applies to all platforms + options: + - All + - Windows + - macOS + - NAS/Synology/QNAP + - Linux/Docker + validations: + required: true +- type: textarea + attributes: + label: Environment + description: Please provide the details of the system NZBGet is running on. The more information you can provide, the better + placeholder: | + Device: + OS version: platform n.nn (32bit/64bit) + CPU architecture: (32bit/64bit) + Includes libs or tool that apply: 7zip x.x, unrar x.x, python3.11 + Running in Docker: No/Yes + render: markdown + validations: + required: true +- type: textarea + attributes: + label: Current Behavior + description: A concise description of what you're experiencing. + validations: + required: true +- type: textarea + attributes: + label: Expected Behavior + description: A concise description of what you expected to happen. + validations: + required: true +- type: textarea + attributes: + label: Steps To Reproduce + description: Steps to reproduce the behavior. + placeholder: | + 1. In this environment... + 2. With this config... + 3. Run '...' + 4. See error... + validations: + required: false +- type: textarea + attributes: + label: Logs + description: | + Any logs or messages that apply + validations: + required: false +- type: textarea + attributes: + label: Extra information + description: | + Please refer to any extra information - extra documentation, attach files or images + validations: + required: false \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/02_feature_request.yml b/.github/ISSUE_TEMPLATE/02_feature_request.yml new file mode 100644 index 000000000..903c175ca --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02_feature_request.yml @@ -0,0 +1,36 @@ +name: Feature Request +description: 'Feature requests or small enhancements' +labels: ['enhancement'] +body: +- type: checkboxes + attributes: + label: Is there already an issue for this request? + description: Please make sure you are not creating an already submitted Issue. Check closed issues as well, because your issue could have been resolved and waiting to be released. + options: + - label: I have checked older issues, open and closed + required: true +- type: dropdown + attributes: + label: Platform + description: Select a specific platform for this request, choose All if it applies to all platforms + options: + - All + - Windows + - macOS + - NAS/Synology/QNAP + - Linux/Docker + validations: + required: true +- type: textarea + attributes: + label: Describe the enhancement you'd like + description: A clear and concise description of what you want to happen. + validations: + required: true +- type: textarea + attributes: + label: Extra information + description: | + Please refer to any extra information - competing product(s) and/or features, extra documentation, attach files or images + validations: + required: false \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/03_build.yml b/.github/ISSUE_TEMPLATE/03_build.yml new file mode 100644 index 000000000..73f9f918a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03_build.yml @@ -0,0 +1,71 @@ +name: Building, compiling, contributing +description: 'Problems building nzbget or questions about contributing' +labels: ['question'] +body: +- type: dropdown + attributes: + label: NZBGet Version + description: Version of NZBGet for the scope of this issue + options: + - v23-stable + - v23-testing + - v22-stable (nzbgetcom takeover) + - v22-testing (nzbgetcom takeover) + - v21 or earlier (orignal nzbget) + validations: + required: true +- type: dropdown + attributes: + label: Platform + description: Select a specific platform for this issue, choose All if it applies to all platforms + options: + - All + - Windows + - macOS + - NAS/Synology/QNAP + - Linux/Docker + validations: + required: true +- type: textarea + attributes: + label: Environment + description: Please provide the details of the system where the issue is observed + placeholder: | + Device: + OS version: platform n.nn (32bit/64bit) + CPU architecture: (32bit/64bit) + Includes libs or tool that apply: 7zip x.x, unrar x.x, python3.11 + render: markdown + validations: + required: true +- type: textarea + attributes: + label: Problem or Question + description: Describe the problem, expected behavior + validations: + required: true +- type: textarea + attributes: + label: Steps To Reproduce + description: Steps to reproduce the behavior. + placeholder: | + 1. In this environment... + 2. With this config... + 3. Run '...' + 4. See error... + validations: + required: false +- type: textarea + attributes: + label: Logs + description: | + Any logs or messages that apply + validations: + required: false +- type: textarea + attributes: + label: Extra information + description: | + Please refer to any extra information - extra documentation, attach files or images + validations: + required: false \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/04_extension.yml b/.github/ISSUE_TEMPLATE/04_extension.yml new file mode 100644 index 000000000..31437b8d5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/04_extension.yml @@ -0,0 +1,25 @@ +# this flow should definitely be impoved with a form - separate suggestions, +# extensions master list and actual extensions questions, TBD + +name: Extension +description: 'Questions, bugs, requests related to Extensions' +labels: ['extension'] +body: +- type: checkboxes + attributes: + label: Is there already an issue for this request? + description: Please make sure you are not creating an already submitted Issue. Check closed issues as well, because your issue could have been resolved and waiting to be released. + options: + - label: I have checked older issues, open and closed + required: true +- type: textarea + attributes: + label: Describe your issue + description: Describe the issue with the extension. Provide as much information as possible + placeholder: | + Existing extension - details about environment - version of nzbget - version of extension - related libs or tools if any. + Please provide as much useful information as possible + .. + Or suggest new extension to be supported with Extension Manager + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..33f5c5936 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: Discussions + url: https://github.com/nzbgetcom/nzbget/discussions + about: Discuss, suggest. Any questions, including performance issues. + - name: NZBGet.com Website + url: https://nzbget.com/contact/ + about: Contact Us via Email From feb0e28880e24ffd3b6bde9dc3c0e0f5ee7b2c85 Mon Sep 17 00:00:00 2001 From: phnzb <139914799+phnzb@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:21:34 +0300 Subject: [PATCH 11/42] Increase develop version to 23.1 (#176) --- CMakeLists.txt | 2 +- configure.ac | 2 +- nzbget.vcxproj | 8 ++++---- osx/NZBGet-Info.plist | 2 +- windows/nzbget-setup.nsi | 2 +- windows/resources/nzbget.rc | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7fed97c3..57f487883 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.22) -set(VERSION "23.0") +set(VERSION "23.1") project( nzbget diff --git a/configure.ac b/configure.ac index b4a8ca9c9..93bdd514e 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.65) -AC_INIT(nzbget, 23.0, https://github.com/nzbgetcom/nzbget/issues) +AC_INIT(nzbget, 23.1, https://github.com/nzbgetcom/nzbget/issues) AC_CONFIG_AUX_DIR(posix) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([foreign subdir-objects]) diff --git a/nzbget.vcxproj b/nzbget.vcxproj index cece1b466..ccf95db08 100755 --- a/nzbget.vcxproj +++ b/nzbget.vcxproj @@ -85,7 +85,7 @@ Disabled C:\vcpkg\installed\x86-windows-static\include;..\bin\Debug32;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\par2;.\lib\yencode;.\windows\resources;.\lib\regex;%(AdditionalIncludeDirectories) - WIN32;PACKAGE="nzbget";VERSION="23.0";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) + WIN32;PACKAGE="nzbget";VERSION="23.1";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) false EnableFastChecks MultiThreadedDebug @@ -107,7 +107,7 @@ Disabled C:\vcpkg\installed\x64-windows-static\include;..\bin\Debug64;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\regex;.\lib\par2;.\lib\yencode;.\windows\resources;%(AdditionalIncludeDirectories) - WIN32;PACKAGE="nzbget";VERSION="23.0";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) + WIN32;PACKAGE="nzbget";VERSION="23.1";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) false EnableFastChecks MultiThreadedDebug @@ -133,7 +133,7 @@ C:\vcpkg\installed\x86-windows-static\include;..\bin\Release32;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\par2;.\lib\yencode;.\windows\resources;.\lib\regex;%(AdditionalIncludeDirectories) - WIN32;PACKAGE="nzbget";VERSION="23.0";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) + WIN32;PACKAGE="nzbget";VERSION="23.1";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) Sync MultiThreaded Use @@ -172,7 +172,7 @@ C:\vcpkg\installed\x64-windows-static\include;..\bin\Release64;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\par2;.\lib\yencode;.\windows\resources;.\lib\regex;%(AdditionalIncludeDirectories) - WIN32;PACKAGE="nzbget";VERSION="23.0";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) + WIN32;PACKAGE="nzbget";VERSION="23.1";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) Sync MultiThreaded Use diff --git a/osx/NZBGet-Info.plist b/osx/NZBGet-Info.plist index ad4f05401..b3069a9b6 100644 --- a/osx/NZBGet-Info.plist +++ b/osx/NZBGet-Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 23.0 + 23.1 CFBundleDocumentTypes diff --git a/windows/nzbget-setup.nsi b/windows/nzbget-setup.nsi index ca5551657..8fb473cda 100644 --- a/windows/nzbget-setup.nsi +++ b/windows/nzbget-setup.nsi @@ -178,7 +178,7 @@ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NZBGet" "U WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NZBGet" "InstallLocation" "$INSTDIR" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NZBGet" "Publisher" "nzbget.com" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NZBGet" "DisplayIcon" "$\"$INSTDIR\nzbget.exe$\",0" -WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NZBGet" "DisplayVersion" "23.0" +WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NZBGet" "DisplayVersion" "23.1" ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 IntFmt $0 "0x%08X" $0 diff --git a/windows/resources/nzbget.rc b/windows/resources/nzbget.rc index 282c55d64..8007f9d94 100644 --- a/windows/resources/nzbget.rc +++ b/windows/resources/nzbget.rc @@ -85,7 +85,7 @@ CAPTION "About NZBGet" FONT 8, "Tahoma", 400, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,63,161,50,14 - CTEXT "Version 23.0",IDC_ABOUT_VERSION,16,70,145,8 + CTEXT "Version 23.1",IDC_ABOUT_VERSION,16,70,145,8 CTEXT "Lightweight usenet downloader",IDC_STATIC,16,83,145,8 CTEXT "https://nzbget.com",IDC_ABOUT_HOMEPAGE,55,144,64,9,SS_NOTIFY ICON "",IDC_ABOUT_ICON,67,7,21,20 From 40234499256c06347ef80853fd66d4bf724c3433 Mon Sep 17 00:00:00 2001 From: phnzb <139914799+phnzb@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:21:41 +0300 Subject: [PATCH 12/42] Update README (#178) --- README.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6a4356d97..cb0de2c38 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ More information available at https://nzbget.com We provide a easy-to-use installer for each platform we support. Please download binaries from our [releases](https://github.com/nzbgetcom/nzbget/tags) page. -We also provide a docker image for popular architectures. [Docker readme](docker/README.md) +Docker images are available for x86-64 / arm64 / armv7 architectures. [Docker readme](docker/README.md) Synology packages are available as SynoCommunity packages and SPK packages. [Synology readme](synology/README.md) @@ -52,7 +52,7 @@ QNAP packages are available as native packages and buildroot packages. [QNAP rea `Windows`: Windows 7 and later, 32 or 64 Bit. -`Linux`: Linux kernel 2.6 and later, x86 (32 or 64 Bit), ARM 32-bit (armel armhf), ARM 64-bit (aarch64) +`Linux`: Linux kernel 2.6 and later, x86 (32 or 64 Bit), ARM 32-bit (armel armhf), ARM 64-bit (aarch64), MIPS (mipseb mipsel), PowerPC (ppc6xx ppc500), RISC-V 64-bit (riscv64) `macOS`: macOS 10.13 High Sierra and later, Intel / Apple Silicon. @@ -60,11 +60,7 @@ QNAP packages are available as native packages and buildroot packages. [QNAP rea [General instructions](INSTALLATION.md) -[Linux cross-compiling / buildroot](linux/build-info.md) - -[macOS](osx/build-info.md) - -[Synology](synology/build-info.md) +[Linux](linux/build-info.md) [macOS](osx/build-info.md) [Synology](synology/build-info.md) [QNAP](qnap/build-info.md) ## Contribution From 0cc6023bfdf7a1d22311dea7d81b8a6ea7a7d880 Mon Sep 17 00:00:00 2001 From: Denis <146707790+dnzbk@users.noreply.github.com> Date: Wed, 21 Feb 2024 01:16:03 -0800 Subject: [PATCH 13/42] Fix and update links in webui (#177) - fixed license links - fixed links from nzbget.conf in webui --- webui/config.js | 2 +- webui/index.html | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/webui/config.js b/webui/config.js index b83ad44ef..7c2b4d420 100644 --- a/webui/config.js +++ b/webui/config.js @@ -955,7 +955,7 @@ var Config = (new function($) }); // replace URLs - exp = /(http:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; + exp = /(https?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; htmldescr = htmldescr.replace(exp, "$1"); // highlight first line diff --git a/webui/index.html b/webui/index.html index 39b435138..2cc18a230 100644 --- a/webui/index.html +++ b/webui/index.html @@ -601,27 +601,27 @@

Copyright

Additional exemption: compiling, linking, and/or using OpenSSL is allowed.

Par2

-

NZBGet uses Par2 by Peter Brian Clements with library interface by Francois Lesueur.

-

Par2 is licensed under the GPL license.

+

NZBGet uses Par2 by Peter Brian Clements with library interface by Francois Lesueur.

+

Par2 is licensed under the GPLv2 license.

jQuery

NZBGet web-interface uses jQuery. The jQuery Project is run by a distributed group of volunteers that all want to see jQuery become the best JavaScript tool possible.

-

jQuery is licensed under the MIT and GPL licenses.

+

jQuery is licensed under the MIT license.

Bootstrap

-

NZBGet web-interface uses Twitter Bootstrap. Designed and built with all the love in the world @twitter by @mdo and @fat.

-

Bootstrap code is licensed under the Apache License v2.0.

+

NZBGet web-interface uses Bootstrap. Designed and built with all the love in the world @twitter by @mdo and @fat.

+

Bootstrap code is licensed under the Apache License v2.0.

Raphaël

-

NZBGet web-interface makes use of Raphaël built by Dmitry Baranovskiy.

-

Raphaël code is licensed under the MIT license.

+

NZBGet web-interface makes use of Raphaël built by Dmitry Baranovskiy.

+

Raphaël code is licensed under the MIT license.

Elycharts

-

For charts NZBGet relies on Elycharts by Void Labs s.n.c.

-

Elycharts code is licensed under the MIT license.

+

For charts NZBGet relies on Elycharts by Void Labs s.n.c.

+

Elycharts code is licensed under the MIT license.

iconSweets

-

NZBGet web-interface includes selected icons from collections iconSweets and iconSweets2 by Yummygum.

+

NZBGet web-interface includes selected icons from collections iconSweets and iconSweets2 by Yummygum.

The icons are generally licensed under a custom license but used in NZBGet with author's permission.

Boost

From 1c03b719f88ece7d67ad348f3aca0d3800ab4d54 Mon Sep 17 00:00:00 2001 From: Denis <146707790+dnzbk@users.noreply.github.com> Date: Wed, 21 Feb 2024 02:11:49 -0800 Subject: [PATCH 14/42] Fix: new stable/testing release notifications (#181) - added automatic checking for new testing releases; - fixed notifications about the new stable/testing release; - fixed "Uncaught ReferenceError: installedRev" error; --- nzbget.conf | 3 ++- webui/config.js | 9 +++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/nzbget.conf b/nzbget.conf index 3572addd0..84efd4093 100644 --- a/nzbget.conf +++ b/nzbget.conf @@ -439,10 +439,11 @@ AuthorizedIP= # NOTE: For more details visit https://nzbget.com/documentation/certificate-verification/. CertCheck=no -# Automatically check for new releases (none, stable). +# Automatically check for new releases (none, stable, testing). # # None - do not show notifcations; # Stable - show notifications about new stable releases; +# Testing - show notifications about new testing releases; UpdateCheck=stable # User name for daemon-mode, POSIX only. diff --git a/webui/config.js b/webui/config.js index 7c2b4d420..9eace742f 100644 --- a/webui/config.js +++ b/webui/config.js @@ -2980,7 +2980,6 @@ var UpdateDialog = (new function($) var installedVer = installedVersion; - var installedTesting = installedVersion.indexOf('testing') > -1; var canInstallStable = UpdateInfo['stable-version'] && (installedVer < UpdateInfo['stable-version']); @@ -3009,11 +3008,9 @@ var UpdateDialog = (new function($) Util.show('#UpdateDialog_CheckFailed', hasUpdateSource && !hasUpdateInfo); Util.show('#UpdateDialog_DownloadRow,#UpdateDialog_DownloadAvail', canDownload && !canUpdate); $('#UpdateDialog_AvailRow').toggleClass('hide', !hasUpdateInfo); - - if (!foreground && - (((canInstallStable || canDownloadStable) && notificationAllowed('stable')) || - (Options.option('UpdateCheck') === 'testing' && installedRev > 0 && - (canInstallTesting || canDownloadTesting) && notificationAllowed('testing')))) + var canUpdateStable = Options.option('UpdateCheck') === 'stable' && (canInstallStable || canDownloadStable) && notificationAllowed('stable'); + var canUpdateTesting = Options.option('UpdateCheck') === 'testing' && (canInstallTesting || canDownloadTesting) && notificationAllowed('testing'); + if (canUpdateStable || canUpdateTesting) { $UpdateDialog.modal({backdrop: 'static'}); } From 56e4225fc73a6d1c7cdc6f647a4cac297e28e9f3 Mon Sep 17 00:00:00 2001 From: Denis <146707790+dnzbk@users.noreply.github.com> Date: Tue, 5 Mar 2024 02:44:25 -0800 Subject: [PATCH 15/42] Switching to CMake from autotools (#182) ## Description - switched to CMake from autotools, which will simplify cross-platform development; - fixed installing/uninstalling on FreeBSD and macOS via autotools/CMake; - added automatic installation of Boost.Json; - added Clang-Tidy static code analizer support; - updated INSTALLATION.md; ## Testing By @dnzbk: - Windows 11 x86_64; - macOS Ventura x86_64; - FreeBSD 13 x86_64; - Linux Debian 12 aarch64/x86_64; By @phnzb - Linux Debian 12 aarch64 - Ubuntu LTS 22.04 / 20.04 x86_64 - Amazon Linux 2 x86_64 - Cross-compilng Linux armhf - macOS Mojave --- .github/workflows/windows-tests.yml | 2 +- .gitignore | 1 - CMakeLists.txt | 141 +++++++---- INSTALLATION.md | 257 ++++++++++++++----- cmake/boost.cmake | 19 ++ cmake/config.h.in | 168 ++++++++++++ cmake/install.cmake | 43 ++++ cmake/posix.cmake | 337 +++++++++++++++++++++++++ cmake/toolchain.cmake | 19 ++ cmake/windows.cmake | 57 +++++ cmake_config.h.in | 5 - daemon/main/Options.cpp | 1 + daemon/main/nzbget.h | 13 +- daemon/sources.cmake | 105 ++++++++ lib/CMakeLists.txt | 45 ---- lib/regex/regex.c | 10 +- lib/regex/regex.h | 4 +- lib/sources.cmake | 98 +++++++ tests/extension/CMakeLists.txt | 12 +- tests/feed/CMakeLists.txt | 10 +- tests/feed/FeedFileTest.cpp | 4 +- tests/main/CMakeLists.txt | 11 +- tests/nntp/CMakeLists.txt | 13 +- tests/nntp/ServerPoolTest.cpp | 14 +- tests/postprocess/CMakeLists.txt | 13 +- tests/postprocess/DirectUnpackTest.cpp | 74 ++++-- tests/queue/CMakeLists.txt | 11 +- tests/queue/NzbFileTest.cpp | 9 +- tests/util/CMakeLists.txt | 18 +- 29 files changed, 1226 insertions(+), 288 deletions(-) create mode 100644 cmake/boost.cmake create mode 100644 cmake/config.h.in create mode 100644 cmake/install.cmake create mode 100644 cmake/posix.cmake create mode 100644 cmake/toolchain.cmake create mode 100644 cmake/windows.cmake delete mode 100644 cmake_config.h.in create mode 100644 daemon/sources.cmake delete mode 100644 lib/CMakeLists.txt create mode 100644 lib/sources.cmake diff --git a/.github/workflows/windows-tests.yml b/.github/workflows/windows-tests.yml index a449de7ed..8fed2240d 100644 --- a/.github/workflows/windows-tests.yml +++ b/.github/workflows/windows-tests.yml @@ -31,7 +31,7 @@ jobs: cmake --version mkdir build cd build - cmake .. "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static + cmake .. -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DBUILD_ONLY_TESTS=ON cmake --build . --config Release -j 2 - name: Test diff --git a/.gitignore b/.gitignore index a5d1eec1d..f10cec75f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,6 @@ # GNU Autotools .deps/ config.h -config.h.in config.h.in~ configure configure~ diff --git a/CMakeLists.txt b/CMakeLists.txt index 57f487883..556ff66c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,57 +1,112 @@ -cmake_minimum_required(VERSION 3.22) +cmake_minimum_required(VERSION 3.13) + +if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) + message(FATAL_ERROR "In-source builds are not allowed. You should create separate directory for build files.") +endif() + +set_property(GLOBAL PROPERTY PACKAGE) +set_property(GLOBAL PROPERTY LIBS) +set_property(GLOBAL PROPERTY INCLUDES) set(VERSION "23.1") +set(PACKAGE "nzbget") +set(PACKAGE_BUGREPORT "https://github.com/nzbgetcom/nzbget/issues") +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_C_EXTENSIONS OFF) +set(CMAKE_CONFIGURATION_TYPES "Release" "Debug") + +add_compile_definitions(HAVE_CONFIG_H=1) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") +endif() + +option(BUILD_ONLY_TESTS "Build only tests (for CI)") project( - nzbget - VERSION ${VERSION} - DESCRIPTION "NZBGet is a binary downloader, which downloads files from Usenet" - LANGUAGES C CXX + nzbget + VERSION ${VERSION} + DESCRIPTION "NZBGet is a binary downloader, which downloads files from Usenet" + LANGUAGES C CXX ) -option(ENABLE_TESTS "Enable tests" ON) +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g0 -pthread -g -Weverything -Wno-c++98-compat" CACHE STRING "" FORCE) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "-O0 -g0 -pthread -g -Wall -Wextra" CACHE STRING "" FORCE) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS "/Od /Zi /MP /W4 /EHs /DDEBUG /D_DEBUG /DWIN32 /wd4800 /wd4267" CACHE STRING "" FORCE) + set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} winmm.lib Dbghelp.lib libcpmtd.lib" CACHE STRING "" FORCE) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebug" CACHE STRING "" FORCE) + endif() +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") + set(CMAKE_CXX_FLAGS "-O2 -g0 -pthread -DNDEBUG -Weverything -Wno-c++98-compat" CACHE STRING "" FORCE) + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" CACHE STRING "" FORCE) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "-O2 -g0 -pthread -DNDEBUG -Wall -Wextra" CACHE STRING "" FORCE) + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" CACHE STRING "" FORCE) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS "/O2 /MP /W4 /EHs /DNDEBUG /DWIN32 /wd4800 /wd4267" CACHE STRING "" FORCE) + set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} winmm.lib" CACHE STRING "" FORCE) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded" CACHE STRING "" FORCE) + endif() +endif() + +set(CMAKE_C_FLAGS_DEBUG ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE) +set(CMAKE_C_FLAGS_RELEASE ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE) -set(PACKAGE "nzbget") -add_compile_definitions(HAVE_CONFIG_H=1) +include_directories(${CMAKE_BINARY_DIR}) +include_directories(${CMAKE_SOURCE_DIR}) + +if(NOT BUILD_ONLY_TESTS) + include(daemon/sources.cmake) + add_executable(${PACKAGE} ${SRC}) +endif() + +if(WIN32) + include(cmake/windows.cmake) + if(NOT BUILD_ONLY_TESTS) + target_sources(${PACKAGE} PRIVATE ${CMAKE_SOURCE_DIR}/windows/resources/nzbget.rc) + endif() +else() + include(cmake/posix.cmake) + if(NOT BUILD_ONLY_TESTS) + include(${CMAKE_SOURCE_DIR}/cmake/install.cmake) + endif() +endif() configure_file( - ${CMAKE_SOURCE_DIR}/cmake_config.h.in - ${CMAKE_BINARY_DIR}/config.h + ${CMAKE_SOURCE_DIR}/cmake/config.h.in + ${CMAKE_BINARY_DIR}/config.h ) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_C_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) -set(CMAKE_C_EXTENSIONS OFF) -set(BUILD_SHARED_LIBS OFF) -set(OPENSSL_USE_STATIC_LIBS ON) -set(ZLIB_USE_STATIC_LIBS ON) -set(Boost_USE_STATIC_LIBS ON) -set(Boost_USE_MULTITHREADED ON) -set(Boost_USE_STATIC_RUNTIME OFF) -set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") - -find_package(OpenSSL REQUIRED) -find_package(ZLIB REQUIRED) -find_package(LibXml2 REQUIRED) -find_package(Boost REQUIRED COMPONENTS json) - -if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Weverything") -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall") -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2 /W4") - set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} winmm.lib /NODEFAULTLIB:msvcrt.lib;libcmt.lib;msvcrtd.lib") +if(NOT BUILD_ONLY_TESTS) + target_link_libraries(${PACKAGE} PRIVATE ${LIBS}) + target_include_directories(${PACKAGE} PRIVATE + ${CMAKE_SOURCE_DIR}/daemon/connect + ${CMAKE_SOURCE_DIR}/daemon/extension + ${CMAKE_SOURCE_DIR}/daemon/feed + ${CMAKE_SOURCE_DIR}/daemon/frontend + ${CMAKE_SOURCE_DIR}/daemon/main + ${CMAKE_SOURCE_DIR}/daemon/nntp + ${CMAKE_SOURCE_DIR}/daemon/nserv + ${CMAKE_SOURCE_DIR}/daemon/postprocess + ${CMAKE_SOURCE_DIR}/daemon/queue + ${CMAKE_SOURCE_DIR}/daemon/remote + ${CMAKE_SOURCE_DIR}/daemon/util + ${INCLUDES} + ) endif() -include_directories(lib/regex) -include_directories(${CMAKE_BINARY_DIR}) -add_subdirectory(lib) - -if(ENABLE_TESTS) - include(CTest) - add_subdirectory(tests) +if(ENABLE_TESTS OR BUILD_ONLY_TESTS) + include(CTest) + add_subdirectory(tests) endif() diff --git a/INSTALLATION.md b/INSTALLATION.md index 2dd0fdefc..1ffac7b1e 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -58,19 +58,24 @@ If you have downloaded binaries you can just jump to section NZBGet is developed on a linux-system, but it runs on other POSIX platforms. -NZBGet absolutely needs the following libraries: +To build NZBGet you will need: - - libstdc++ (usually part of compiler) +For configuring and building: + - [CMake](https://cmake.org/) + - [GCC](https://gcc.gnu.org/) + + or + - [CLang](https://clang.llvm.org/) + +Libraries: - [libxml2](https://gitlab.gnome.org/GNOME/libxml2/-/wikis/home) - [Boost.JSON](https://www.boost.org/doc/libs/1_84_0/libs/json/doc/html/index.html) - - [Boost.Optional](https://www.boost.org/doc/libs/1_84_0/libs/optional/doc/html/index.html) +> If you face issues with Boost.JSON on your system, you can skip it - CMake will take care of it. And the following libraries are optional: For curses-output-mode (enabled by default): - - libcurses (usually part of commercial systems) - or (better) - - [libncurses](https://invisible-island.net/ncurses) + - [ncurses](https://invisible-island.net/ncurses) For encrypted connections (TLS/SSL): - [OpenSSL](https://www.openssl.org) @@ -80,60 +85,159 @@ And the following libraries are optional: For gzip support in web-server and web-client (enabled by default): - [zlib](https://www.zlib.net/) - - For configuration: - - [autotools](https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html) - - [autoconf](https://www.gnu.org/software/autoconf/) - - For managing package dependencies: - - [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) For tests: - [Boost.Test](https://www.boost.org/doc/libs/1_84_0/libs/test/doc/html/index.html) -All these libraries are included in modern POSIX distributions and -should be available as installable packages. Please note that you also + For static code analysis: + - [Clang-Tidy](https://clang.llvm.org/extra/clang-tidy/) + +Please note that you also need the developer packages for these libraries too, they package names have often suffix "dev" or "devel". On other systems you may need to download the libraries at the given URLs and compile them (see hints below). +### Debian: +``` + apt install cmake build-essential libncurses-dev libssl-dev libxml2-dev zlib1g-dev libboost-json1.81-dev +``` + - For tests: +``` + apt install libboost-test1.81-dev +``` + - For static code analysis: +``` + apt install clang-tidy +``` +### FreeBSD: +``` + pkg install cmake ncurses openssl libxml2 zlib boost-libs +``` +### macOS: +``` + xcode-select --install + brew install cmake ncurses openssl libxml2 zlib boost +``` + ## 4. Installation on POSIX Installation from the source distribution archive (nzbget-VERSION.tar.gz): - - untar the nzbget-source via - tar -zxf nzbget-VERSION.tar.gz - - - change into nzbget-directory via - cd nzbget-VERSION - - - configure it via - - autoreconf --install - - ./configure + - Untar the nzbget-source: +``` + tar -zxf nzbget-VERSION.tar.gz +``` + - Change into nzbget-directory: +``` + cd nzbget-VERSION +``` + - Configure: +``` + mkdir build + cd build + cmake .. +``` + - In a case you don't have root access or want to install the program + in your home directory use the configure parameter -DCMAKE_INSTALL_PREFIX: +``` + cmake .. -DCMAKE_INSTALL_PREFIX=~/usr +``` + - Build, specifying (-j 8) how many CPU cores to use to speed up compilation: +``` + cmake --build . -j 8 +``` + - Install: +``` + cmake --install . +``` + - Uninstall: +``` + cmake --build . --target uninstall +``` - (maybe you have to tell configure, where to find some libraries. - ./configure --help is your friend! - also see "Configure-options" later) +### Configure-options +--------------------- +You may run configure with additional arguments: + - Enable tests: +``` + cmake .. -DENABLE_TESTS=ON +``` + - Enable Clang-Tidy static code analizer: +``` + cmake .. -DENABLE_CLANG_TIDY=ON +``` + - Disable ncurses. Use this option if you can not use ncurses. +``` + cmake .. -DDISABLE_CURSES=ON +``` + - Disable parcheck. Use this option if you have troubles when compiling par2-module. +``` + cmake .. -DDISABLE_PARCHECK=ON +``` + - Use GnuTLS. Use this option if you want to use GnuTLS instead of OpenSSL. +``` + cmake .. -DUSE_GNUTLS=ON +``` + - Disable TLS. Use this option if you can not neither OpenSSL nor GnuTLS. +``` + cmake .. -DDISABLE_TLS=ON +``` + - Disable gzip. Use this option if you can not use zlib. +``` + cmake .. -DDISABLE_GZIP=ON +``` + - Disable sigchld-handler. The disabling may be neccessary on 32-Bit BSD. +``` + cmake .. -DDISABLE_SIGCHLD_HANDLER=ON +``` + - For debug build. +``` + cmake .. -DCMAKE_BUILD_TYPE=Debug +``` + - To get a static binary, +``` + cmake .. -DENABLE_STATIC=ON +``` + `LIBS` and `INCLUDES` env variables can be useful for static linking, since CMake looks for shared libraries by default +``` + export LIBS="-lncurses -ltinfo -lboost_json -lxml2 -lz -lm -lssl -lcrypto -Wl,--whole-archive -lpthread -Wl,--no-whole-archive" + export INCLUDES="/usr/include/;/usr/include/libxml2/" + cmake .. -DENABLE_STATIC=ON +``` +## Building using autotools (deprecated) + + - configure it via +``` + autoreconf --install + ./configure +``` + (maybe you have to tell configure, where to find some libraries then is your friend! +``` + ./configure --help +``` + also see "Configure-options" later) - in a case you don't have root access or want to install the program in your home directory use the configure parameter --prefix, e. g.: - +``` ./configure --prefix ~/usr - +``` - compile it via - make - +``` + make +``` - to install system wide become root via: - su - +``` + su +``` - install it via: - make install - +``` + make install +``` - install configuration files into /etc via: - make install-conf - +``` + make install-conf +``` (you can skip this step if you intend to store configuration files in a non-standard location) @@ -143,22 +247,22 @@ You may run configure with additional arguments: --disable-curses - to make without curses-support. Use this option if you can not use curses/ncurses. - + --disable-parcheck - to make without parcheck-support. Use this option if you have troubles when compiling par2-module. --with-tlslib=(OpenSSL, GnuTLS) - to select which TLS/SSL library should be used for encrypted server connections. - + --disable-tls - to make without TLS/SSL support. Use this option if you can not neither OpenSSL nor GnuTLS. --disable-gzip - to make without gzip support. Use this option if you can not use zlib. - + --enable-debug - to build in debug-mode, if you want to see and log debug-messages. - + ### Optional package: par-check ------------------------------- NZBGet can check and repair downloaded files for you. For this purpose @@ -169,8 +273,9 @@ NZBGet’s source tree and is compiled automatically when you make NZBGet. In a case errors occur during this process the inclusion of par2-module can be disabled using configure option "--disable-parcheck": - +``` ./configure --disable-parcheck +``` ### Optional package: curses ---------------------------- @@ -183,8 +288,9 @@ Following configure-parameters may be useful: If you are not able to use curses or ncurses or do not want them you can make the program without support for curses using option "--disable-curses": - +``` ./configure --disable-curses +``` ### Optional package: TLS ------------------------- @@ -193,9 +299,10 @@ with TLS/SSL support. NZBGet can use two libraries: OpenSSL or GnuTLS. Configure-script checks which library is installed and use it. If both are available it gives the precedence to OpenSSL. You may override that with the option --with-tlslib=(OpenSSL, GnuTLS). For example to build with GnuTLS: - +``` ./configure --with-tlslib= GnuTLS - +``` + Following configure-parameters may be useful: --with-libtls-includess=/path/to/gnutls/includes @@ -208,29 +315,65 @@ If none of these libraries is available you can make the program without TLS/SSL support using option "--disable-tls": ./configure --disable-tls - + ## 5. Compiling on Windows -NZBGet is developed using MS Visual Studio 2015 (Community Edition). The project -file is provided. +For configuring and building: + - [CMake](https://cmake.org/) + - [MS C++ Build tools](https://visualstudio.microsoft.com/downloads/?q=build+tools) -To compile the program with TLS/SSL support you need either OpenSSL or GnuTLS: +To compile the program with TLS/SSL support you need OpenSSL: - [OpenSSL](https://www.openssl.org) - or - - [GnuTLS](https://gnutls.org/) - Also required are: - - [Regex](https://regexlib.com/) - [Zlib](https://gnuwin32.sourceforge.net/packages/zlib.htm) - [libxml2](https://gitlab.gnome.org/GNOME/libxml2/-/wikis/home) - [Boost.JSON](https://www.boost.org/doc/libs/1_84_0/libs/json/doc/html/index.html) - [Boost.Optional](https://www.boost.org/doc/libs/1_84_0/libs/optional/doc/html/index.html) - For tests: - [Boost.Test](https://www.boost.org/doc/libs/1_84_0/libs/test/doc/html/index.html) -We recommend using [vcpkg](https://vcpkg.io/) to install dependencies. +We recommend using [vcpkg](https://vcpkg.io/) to install dependencies: + +``` + vcpkg install openssl:-windows-static + vcpkg install libxml2:-windows-static + vcpkg install zlib:-windows-static + vcpkg install boost-json:-windows-static + vcpkg install boost-optional:-windows-static +``` + - For tests: +``` + vcpkg install boost-test:-windows-static +``` + - Configure: +``` + mkdir build + cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -A x64 +``` + - For Win32: +``` + cmake .. -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x86-windows-static -A Win32 +``` + - For debug build: +``` + cmake .. -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_BUILD_TYPE=Debug +``` + - If Debug: +``` + cmake --build . --config Debug +``` + +You may run configure with additional arguments: + - Enable tests: +``` + cmake .. -DENABLE_TESTS=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static +``` + - Disable TLS. Use this option if you can not neither OpenSSL nor GnuTLS. +``` + cmake .. -DDISABLE_TLS=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static +``` ## 6. Configuration diff --git a/cmake/boost.cmake b/cmake/boost.cmake new file mode 100644 index 000000000..7d517368e --- /dev/null +++ b/cmake/boost.cmake @@ -0,0 +1,19 @@ +set(ROOT ${CMAKE_BINARY_DIR}/boost/) + +ExternalProject_add( + boost + PREFIX boost + URL https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.xz + TLS_VERIFY TRUE + BUILD_IN_SOURCE TRUE + GIT_SHALLOW TRUE + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + CONFIGURE_COMMAND ${ROOT}src/boost/bootstrap.sh + --with-libraries=json + --prefix=${ROOT}build + BUILD_COMMAND ${ROOT}src/boost/b2 link=static + INSTALL_COMMAND ${ROOT}src/boost/b2 install +) + +set(LIBS ${LIBS} ${ROOT}build/lib/libboost_json.a) +set(INCLUDES ${INCLUDES} ${ROOT}build/include/) diff --git a/cmake/config.h.in b/cmake/config.h.in new file mode 100644 index 000000000..0e8e0cfe3 --- /dev/null +++ b/cmake/config.h.in @@ -0,0 +1,168 @@ +/* Name of package */ +#cmakedefine PACKAGE "@PACKAGE@" + +/* Version number of package */ +#cmakedefine VERSION "@VERSION@" + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" + +/* Define to 1 to not use curses */ +#cmakedefine DISABLE_CURSES + +/* Define to 1 to disable gzip-support */ +#cmakedefine DISABLE_GZIP + +/* Define to 1 to not use libxml2, only for development purposes */ +#cmakedefine DISABLE_LIBXML2 + +/* Define to 1 to disable par-verification and repair */ +#cmakedefine DISABLE_PARCHECK + +/* Define to 1 to not use TLS/SSL */ +#cmakedefine DISABLE_TLS + +/* Define to 1 to install an empty signal handler for SIGCHLD */ +#cmakedefine SIGCHLD_HANDLER @SIGCHLD_HANDLER@ + +/* Define to the name of macro which returns the name of function being + compiled */ +#cmakedefine FUNCTION_MACRO_NAME @FUNCTION_MACRO_NAME@ + +/* Define to 1 to create stacktrace on segmentation faults */ +#cmakedefine HAVE_BACKTRACE @HAVE_BACKTRACE@ + +/* Define to 1 if ctime_r takes 2 arguments */ +#cmakedefine HAVE_CTIME_R_2 @HAVE_CTIME_R_2@ + +/* Define to 1 if ctime_r takes 3 arguments */ +#cmakedefine HAVE_CTIME_R_3 @HAVE_CTIME_R_3@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_CURSES_H @HAVE_CURSES_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ENDIAN_H @HAVE_ENDIAN_H@ + +/* Define to 1 if fdatasync is supported */ +#cmakedefine HAVE_FDATASYNC @HAVE_FDATASYNC@ + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#cmakedefine HAVE_FSEEKO @HAVE_FSEEKO@ + +/* Define to 1 if F_FULLFSYNC is supported */ +#cmakedefine HAVE_FULLFSYNC @HAVE_FULLFSYNC@ + +/* Define to 1 if getaddrinfo is supported */ +#cmakedefine HAVE_GETADDRINFO @HAVE_GETADDRINFO@ + +/* Define to 1 if gethostbyname_r is supported */ +#cmakedefine HAVE_GETHOSTBYNAME_R @HAVE_GETHOSTBYNAME_R@ + +/* Define to 1 if gethostbyname_r takes 3 arguments */ +#cmakedefine HAVE_GETHOSTBYNAME_R_3 @HAVE_GETHOSTBYNAME_R_3@ + +/* Define to 1 if gethostbyname_r takes 5 arguments */ +#cmakedefine HAVE_GETHOSTBYNAME_R_5 @HAVE_GETHOSTBYNAME_R_5@ + +/* Define to 1 if gethostbyname_r takes 6 arguments */ +#cmakedefine HAVE_GETHOSTBYNAME_R_6 @HAVE_GETHOSTBYNAME_R_6@ + +/* Define to 1 if you have the `getopt' function. */ +#cmakedefine HAVE_GETOPT @HAVE_GETOPT@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GETOPT_H @HAVE_GETOPT_H@ + +/* Define to 1 if getopt_long is supported */ +#cmakedefine HAVE_GETOPT_LONG @HAVE_GETOPT_LONG@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@ + +/* Define to 1 to use GnuTLS library for TLS/SSL-support. */ +#cmakedefine HAVE_LIBGNUTLS @HAVE_LIBGNUTLS@ + +/* Define to 1 if lockf is supported */ +#cmakedefine HAVE_LOCKF @HAVE_LOCKF@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NCURSES_H @HAVE_NCURSES_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NCURSES_NCURSES_H @HAVE_NCURSES_NCURSES_H@ + +/* Define to 1 to use Nettle library for decryption. */ +#cmakedefine HAVE_NETTLE @HAVE_NETTLE@ + +/* Define to 1 to use OpenSSL library for TLS/SSL-support and decryption. */ +#cmakedefine HAVE_OPENSSL @HAVE_OPENSSL@ + +/* Define to 1 if pthread_cancel is supported */ +#cmakedefine HAVE_PTHREAD_CANCEL @HAVE_PTHREAD_CANCEL@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_REGEX_H @HAVE_REGEX_H@ + +/* Define to 1 if _SC_NPROCESSORS_ONLN is present in unistd.h */ +#cmakedefine HAVE_SC_NPROCESSORS_ONLN @HAVE_SC_NPROCESSORS_ONLN@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDIO_H @HAVE_STDIO_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H @HAVE_STRING_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_PRCTL_H @HAVE_SYS_PRCTL_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@ + +/* Define to 1 if variadic macros are supported */ +#cmakedefine HAVE_VARIADIC_MACROS @HAVE_VARIADIC_MACROS@ + +/* Define to 1 if OpenSSL supports function "X509_check_host" */ +#cmakedefine HAVE_X509_CHECK_HOST @HAVE_X509_CHECK_HOST@ + +/* Determine what socket length (socklen_t) data type is */ +#cmakedefine SOCKLEN_T @SOCKLEN_T@ + +/* Number of bits in a file offset, on hosts where this is settable. */ +#cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@ + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +#cmakedefine _LARGEFILE_SOURCE @_LARGEFILE_SOURCE@ + +/* Define for large files, on AIX-style hosts. */ +#cmakedefine _LARGE_FILES @_LARGE_FILES@ + +/* Define to `unsigned int' if does not define. */ +#cmakedefine size_t @size_t@ + +/* Define if AMD64 */ +#cmakedefine __amd64__ + +/* Define if i686 */ +#cmakedefine __i686__ + +/* Use 32BIT TIME_T */ +#cmakedefine _USE_32BIT_TIME_T + +/* detection of memory leaks */ +#cmakedefine _CRTDBG_MAP_ALLOC diff --git a/cmake/install.cmake b/cmake/install.cmake new file mode 100644 index 000000000..3175b3bec --- /dev/null +++ b/cmake/install.cmake @@ -0,0 +1,43 @@ +set(DOC_FILES + ${CMAKE_SOURCE_DIR}/ChangeLog + ${CMAKE_SOURCE_DIR}/COPYING +) +set(SHARE_DIR ${CMAKE_INSTALL_PREFIX}/share/${PACKAGE}) +set(CONF_FILE ${CMAKE_SOURCE_DIR}/nzbget.conf) +set(WEBUI_DIR ${CMAKE_SOURCE_DIR}/webui) +set(DOC_FILES_DEST ${SHARE_DIR}/doc) +set(CONF_FILE_DEST ${SHARE_DIR}) +set(WEBUI_DIR_DEST ${SHARE_DIR}) +set(BIN_FILE_DEST ${CMAKE_INSTALL_PREFIX}/bin) + +install(TARGETS ${PACKAGE} PERMISSIONS + OWNER_EXECUTE + OWNER_WRITE + OWNER_READ + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE + DESTINATION ${BIN_FILE_DEST}) +install(FILES ${DOC_FILES} DESTINATION ${DOC_FILES_DEST}) +install(DIRECTORY ${WEBUI_DIR} DESTINATION ${WEBUI_DIR_DEST}) + +file(READ ${CONF_FILE} CONFIG_CONTENT) +string(REPLACE "WebDir=" "WebDir=${WEBUI_DIR_DEST}/webui" MODIFIED_CONFIG_CONTENT "${CONFIG_CONTENT}") +string(REPLACE "ConfigTemplate=" "ConfigTemplate=${CONF_FILE_DEST}/nzbget.conf" MODIFIED_CONFIG_CONTENT "${MODIFIED_CONFIG_CONTENT}") +file(WRITE ${CMAKE_BINARY_DIR}/nzbget.conf "${MODIFIED_CONFIG_CONTENT}") +install(FILES ${CMAKE_BINARY_DIR}/nzbget.conf DESTINATION ${CONF_FILE_DEST}) + +if(NOT EXISTS ${CMAKE_INSTALL_PREFIX}/etc/nzbget.conf) + install(FILES ${CMAKE_BINARY_DIR}/nzbget.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/etc) +else() + message(STATUS "nzbget.conf is already installed in ${CMAKE_INSTALL_PREFIX}/etc") + message(STATUS "If you want to overwrite it, then do it manually with caution") +endif() + +add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -E remove_directory ${DOC_FILES_DEST} + COMMAND ${CMAKE_COMMAND} -E remove_directory ${SHARE_DIR} + COMMAND ${CMAKE_COMMAND} -E remove ${BIN_FILE_DEST}/${PACKAGE} + COMMENT "Uninstalling" ${PACKAGE} +) diff --git a/cmake/posix.cmake b/cmake/posix.cmake new file mode 100644 index 000000000..376d92ea1 --- /dev/null +++ b/cmake/posix.cmake @@ -0,0 +1,337 @@ +option(ENABLE_STATIC "Build static executable") +option(ENABLE_TESTS "Build tests") +option(ENABLE_CLANG_TIDY "Enable Clang-Tidy static analizer") +option(DISABLE_TLS "Disable TLS") +option(DISABLE_CURSES "Disable curses") +option(DISABLE_GZIP "Disable gzip") +option(DISABLE_PARCHECK "Disable parcheck") +option(USE_OPENSSL "Use OpenSSL" ON) +option(USE_GNUTLS "Use GnuTLS" OFF) + +if(NOT DISABLE_TLS AND USE_GNUTLS) + set(USE_OPENSSL OFF) +endif() + +if(DISABLE_TLS) + set(USE_GNUTLS OFF) + set(USE_OPENSSL OFF) +endif() + +message(STATUS "TOOLCHAIN OPTIONS:") +message(STATUS " SYSTEM NAME ${CMAKE_SYSTEM_NAME}") +message(STATUS " SYSTEM PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}") +message(STATUS "BUILD OPTIONS:") +message(STATUS " BUILD TYPE: ${CMAKE_BUILD_TYPE}") +message(STATUS " ENABLE STATIC: ${ENABLE_STATIC}") +message(STATUS " ENABLE TESTS: ${ENABLE_TESTS}") +message(STATUS " DISABLE TLS: ${DISABLE_TLS}") +message(STATUS " - OPENSSL: ${USE_OPENSSL}") +message(STATUS " - GNUTLS: ${USE_GNUTLS}") +message(STATUS " DISABLE CURSES: ${DISABLE_CURSES}") +message(STATUS " DISABLE GZIP: ${DISABLE_GZIP}") +message(STATUS " DISABLE PARCHECK: ${DISABLE_PARCHECK}") + +if(ENABLE_CLANG_TIDY) + set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=-*,readability-*) +endif() + +if(ENABLE_STATIC) + # due to the error "ld: library not found for -crt0.o" when using Apple Clang with "-static" + if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-static" CACHE STRING "" FORCE) + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -static" CACHE STRING "" FORCE) + endif() + set(BUILD_SHARED_LIBS OFF) + set(LIBS $ENV{LIBS}) + set(INCLUDES $ENV{INCLUDES}) + include(${CMAKE_SOURCE_DIR}/lib/sources.cmake) +else() + find_package(Threads REQUIRED) + find_package(LibXml2 REQUIRED) + + set(LIBS ${LIBS} Threads::Threads LibXml2::LibXml2) + set(INCLUDES ${INCLUDES} ${LIBXML2_INCLUDE_DIR}) + + if(NOT DISABLE_TLS) + if(USE_OPENSSL AND NOT USE_GNUTLS) + find_package(OpenSSL REQUIRED) + set(LIBS ${LIBS} OpenSSL::SSL OpenSSL::Crypto) + set(INCLUDES ${INCLUDES} ${OPENSSL_INCLUDE_DIR}) + elseif(USE_GNUTLS) + find_package(GnuTLS REQUIRED) + find_library(NETTLE_LIBRARY NAMES nettle libnettle) + set(INCLUDES ${INCLUDES} ${GNUTLS_INCLUDE_DIRS}) + set(LIBS ${LIBS} GnuTLS::GnuTLS ${NETTLE_LIBRARY}) + endif() + endif() + + if(NOT DISABLE_CURSES) + set(CURSES_NEED_NCURSES TRUE) + find_package(Curses REQUIRED) + set(INCLUDES ${INCLUDES} ${CURSES_INCLUDE_DIRS}) + set(LIBS ${LIBS} ${CURSES_LIBRARIES}) + endif() + + if(NOT DISABLE_GZIP) + find_package(ZLIB REQUIRED) + set(INCLUDES ${INCLUDES} ${ZLIB_INCLUDE_DIRS}) + set(LIBS ${LIBS} ZLIB::ZLIB) + endif() + + find_package(Boost COMPONENTS json) + + if(NOT Boost_JSON_FOUND) + message(STATUS "The Boost library will be installed from github") + include(ExternalProject) + + include(${CMAKE_SOURCE_DIR}/cmake/boost.cmake) + + include(${CMAKE_SOURCE_DIR}/lib/sources.cmake) + + add_dependencies(${PACKAGE} boost) + add_dependencies(yencode boost) + add_dependencies(par2 boost) + add_dependencies(regex boost) + else() + set(LIBS ${LIBS} Boost::json) + set(INCLUDES ${INCLUDES} ${Boost_INCLUDE_DIR}) + + include(${CMAKE_SOURCE_DIR}/lib/sources.cmake) + endif() +endif() + +include(CheckIncludeFiles) +include(CheckLibraryExists) +include(CheckSymbolExists) +include(CheckFunctionExists) +include(CheckTypeSize) +include(CheckCSourceCompiles) +include(CheckCXXSourceCompiles) + +check_include_files(sys/prctl.h HAVE_SYS_PRCTL_H) +check_include_files(regex.h HAVE_REGEX_H) +check_include_files(endian.h HAVE_ENDIAN_H) +check_include_files(getopt.h HAVE_GETOPT_H) +check_include_file(inttypes.h HAVE_INTTYPES_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(stdio.h HAVE_STDIO_H) +check_include_file(stdlib.h HAVE_STDLIB_H) +check_include_file(strings.h HAVE_STRINGS_H) +check_include_file(string.h HAVE_STRING_H) +check_include_file(sys/stat.h HAVE_SYS_STAT_H) +check_include_file(unistd.h HAVE_UNISTD_H) + +check_library_exists(pthread pthread_create "" HAVE_PTHREAD_CREATE) +check_library_exists(socket socket "" HAVE_SOCKET) +check_library_exists(nsl inet_addr "" HAVE_INET_ADDR) +check_library_exists(resolv hstrerror "" HAVE_HSTRERROR) + +check_symbol_exists(lockf unistd.h HAVE_LOCKF) +check_symbol_exists(pthread_cancel pthread.h HAVE_PTHREAD_CANCEL) +check_symbol_exists(F_FULLFSYNC fcntl.h HAVE_FULLFSYNC) + +check_function_exists(getopt_long HAVE_GETOPT_LONG) +check_function_exists(fdatasync HAVE_FDATASYNC) + +set(SIGCHLD_HANDLER 1) + +if(USE_OPENSSL) + set(HAVE_OPENSSL 1) +endif() + +if(USE_GNUTLS) + set(HAVE_LIBGNUTLS 1) + set(HAVE_NETTLE 1) +endif() + +if(NOT DISABLE_CURSES) + set(HAVE_NCURSES_H 1) +endif() + +if(NOT DISABLED_PARCHECK) + check_type_size(size_t SIZE_T) + check_symbol_exists(fseeko "stdio.h" HAVE_FSEEKO) + check_function_exists(getopt HAVE_GETOPT) +else() + set(DISABLED_PARCHECK 1) +endif() + +# check ctime_r +check_cxx_source_compiles(" + #include + int main() + { + time_t clock; + char buf[26]; + ctime_r(&clock, buf, 26); + return 0; + }" HAVE_CTIME_R_3) + +if(NOT HAVE_CTIME_R_3) + check_cxx_source_compiles(" + #include + int main() + { + time_t clock; + char buf[26]; + ctime_r(&clock, buf); + return 0; + }" HAVE_CTIME_R_2) +endif() +if(NOT HAVE_CTIME_R_2) + message(FATAL_ERROR "ctime_r function not found") +endif() + +check_function_exists(getaddrinfo HAVE_GETADDRINFO) +if(NOT HAVE_GETADDRINFO) + check_library_exists(nsl getaddrinfo "" HAVE_GETADDRINFO) +endif() + +# check gethostbyname_r, if getaddrinfo is not available +if(NOT HAVE_GETADDRINFO) + check_cxx_source_compiles(" + #include + int main() + { + char* szHost; + struct hostent hinfobuf; + char* strbuf; + int h_errnop; + struct hostent* hinfo = gethostbyname_r(szHost, &hinfobuf, strbuf, 1024, &h_errnop); + return 0; + }" HAVE_GETHOSTBYNAME_R_5) +if(NOT HAVE_GETHOSTBYNAME_R_5) + check_cxx_source_compiles(" + #include + int main() + { + char* szHost; + struct hostent* hinfo; + struct hostent hinfobuf; + char* strbuf; + int h_errnop; + int err = gethostbyname_r(szHost, &hinfobuf, strbuf, 1024, &hinfo, &h_errnop); + return 0; + }" HAVE_GETHOSTBYNAME_R_6) +if(NOT HAVE_GETHOSTBYNAME_R_6) + check_cxx_source_compiles(" + #include + int main() + { + char* szHost; + struct hostent hinfo; + struct hostent_data hinfobuf; + int err = gethostbyname_r(szHost, &hinfo, &hinfobuf); + return 0; + }" HAVE_GETHOSTBYNAME_R_3) +if(NOT HAVE_GETHOSTBYNAME_R_3) + message(FATAL_ERROR "gethostbyname_r function not found") +endif() +endif() +endif() +if (NOT HAVE_GETHOSTBYNAME_R_3) + set(HAVE_GETHOSTBYNAME_R 1) + check_library_exists(nsl gethostbyname_r "" HAVE_GETHOSTBYNAME_R) +endif() +endif() + +# Determine what socket length (socklen_t) data type is +check_cxx_source_compiles(" + #include + #include + #include + int main() + { + (void)getsockopt (1, 1, 1, NULL, (socklen_t*)NULL); + }" SOCKLEN) +if(SOCKLEN) + set(SOCKLEN_T socklen_t) +else() + check_cxx_source_compiles(" + #include + #include + #include + int main() + { + (void)getsockopt (1, 1, 1, NULL, (size_t*)NULL); + }" SOCKLEN) +if(SOCKLEN) + set(SOCKLEN_T size_t) +else() + check_cxx_source_compiles(" + #include + #include + #include + int main() + { + (void)getsockopt (1, 1, 1, NULL, (int*)NULL); + }" SOCKLEN) +if(SOCKLEN) + set(SOCKLEN_T int) +else() + set(SOCKLEN_T int) +endif() +endif() +endif() + +# Check CPU cores via sysconf +check_cxx_source_compiles(" + #include + int main() + { + int a = _SC_NPROCESSORS_ONLN; + }" HAVE_SC_NPROCESSORS_ONLN) + +# Check TLS/SSL +if(USE_OPENSSL AND NOT ENABLE_STATIC) + check_library_exists(OpenSSL::Crypto X509_check_host "" HAVE_X509_CHECK_HOST) +endif() + +check_cxx_source_compiles(" + #include + int main() + { + printf(\"%s\", __FUNCTION__); + return 0; + }" FUNCTION_MACRO_NAME_ONE) + +check_cxx_source_compiles(" + #include + int main() + { + printf(\"%s\", __func__); + return 0; + }" FUNCTION_MACRO_NAME_TWO) + +if(FUNCTION_MACRO_NAME_ONE) + set(FUNCTION_MACRO_NAME __FUNCTION__) +elseif (FUNCTION_MACRO_NAME_TWO) + set(FUNCTION_MACRO_NAME __func__) +endif() + +check_cxx_source_compiles(" + #define macro(...) macrofunc(__VA_ARGS__) + int macrofunc(int a, int b) { return a + b; } + int main() + { + int a = macro(1, 2); + return 0; + }" HAVE_VARIADIC_MACROS) + +if(HAVE_VARIADIC_MACROS) + set(DHAVE_VARIADIC_MACROS 1) +endif() + +check_cxx_source_compiles(" + #include + #include + #include + int main() + { + void* array[100]; + size_t size; + char** strings; + size = backtrace(array, 100); + strings = backtrace_symbols(array, size); + return 0; + }" HAVE_BACKTRACE) diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake new file mode 100644 index 000000000..329786886 --- /dev/null +++ b/cmake/toolchain.cmake @@ -0,0 +1,19 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR ${ARCH}) + +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_AR ${TOOLCHAIN_PREFIX}-ar) +set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}-as) +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}-ld) +set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}-objcopy) +set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}-ranlib) +set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}-size) +set(CMAKE_STRIP ${TOOLCHAIN_PREFIX}-strip) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/cmake/windows.cmake b/cmake/windows.cmake new file mode 100644 index 000000000..bfc265bd7 --- /dev/null +++ b/cmake/windows.cmake @@ -0,0 +1,57 @@ +option(ENABLE_TESTS "Enable tests") +option(DISABLE_TLS "Disable TLS") + +message(STATUS "TOOLCHAIN OPTIONS:") +message(STATUS " SYSTEM NAME ${CMAKE_SYSTEM_NAME}") +message(STATUS " SYSTEM PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}") +message(STATUS " TARGET TRIPLET ${VCPKG_TARGET_TRIPLET}") +message(STATUS "BUILD OPTIONS:") +message(STATUS " BUILD TYPE: ${CMAKE_BUILD_TYPE}") +message(STATUS " ENABLE TESTS: ${ENABLE_TESTS}") +message(STATUS " DISABLE TLS: ${DISABLE_TLS}") + +set(Boost_USE_STATIC_LIBS ON) + +find_package(Threads REQUIRED) +find_package(LibXml2 REQUIRED) +find_package(Boost REQUIRED COMPONENTS json) + +set(LIBS Threads::Threads Boost::json LibXml2::LibXml2) +set(INCLUDES ${Boost_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR}) + +if(NOT DISABLE_TLS) + find_package(OpenSSL REQUIRED) + set(HAVE_OPENSSL 1) + set(HAVE_X509_CHECK_HOST 1) + set(LIBS ${LIBS} OpenSSL::SSL OpenSSL::Crypto) + set(INCLUDES ${INCLUDES} ${OPENSSL_INCLUDE_DIR}) +endif() + +find_package(ZLIB REQUIRED) +set(LIBS ${LIBS} ZLIB::ZLIB) +set(INCLUDES ${INCLUDES} ${ZLIB_INCLUDE_DIRS}) + +include(${CMAKE_SOURCE_DIR}/lib/sources.cmake) +set(INCLUDES ${INCLUDES} + ${CMAKE_SOURCE_DIR}/daemon/windows + ${CMAKE_SOURCE_DIR}/windows/resources +) + +set(FUNCTION_MACRO_NAME __FUNCTION__) +set(HAVE_CTIME_R_3 1) +set(HAVE_VARIADIC_MACROS 1) +set(HAVE_GETADDRINFO 1) +set(SOCKLEN_T socklen_t) +set(HAVE_REGEX_H 1) +set(HAVE_STDINT_H 1) + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(__amd64__ 1) +else() + set(__i686__ 1) + set(_USE_32BIT_TIME_T 1) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(_CRTDBG_MAP_ALLOC 1) +endif() diff --git a/cmake_config.h.in b/cmake_config.h.in deleted file mode 100644 index aa35cd479..000000000 --- a/cmake_config.h.in +++ /dev/null @@ -1,5 +0,0 @@ -/* Name of package */ -#cmakedefine PACKAGE "@PACKAGE@" - -/* Version number of package */ -#cmakedefine VERSION "@VERSION@" diff --git a/daemon/main/Options.cpp b/daemon/main/Options.cpp index b10b6bda7..ead51f061 100644 --- a/daemon/main/Options.cpp +++ b/daemon/main/Options.cpp @@ -187,6 +187,7 @@ const char* PossibleConfigLocations[] = "/usr/etc/nzbget.conf", "/usr/local/etc/nzbget.conf", "/opt/etc/nzbget.conf", + "~/usr/etc/nzbget.conf", nullptr }; #endif diff --git a/daemon/main/nzbget.h b/daemon/main/nzbget.h index 98bd04fa8..2ec287b6d 100644 --- a/daemon/main/nzbget.h +++ b/daemon/main/nzbget.h @@ -112,11 +112,9 @@ compiled */ #endif - /***************** GLOBAL INCLUDES *****************/ #ifdef WIN32 - // WINDOWS INCLUDES // Using "WIN32_LEAN_AND_MEAN" to disable including of many unneeded headers @@ -138,14 +136,8 @@ compiled */ #include #include #include - #include -#if _MSC_VER >= 1600 -#include -#define HAVE_STDINT_H -#endif - #ifdef _DEBUG #include #endif @@ -159,9 +151,7 @@ compiled */ #include #include #include -#include #include -#include #include #include #include @@ -172,8 +162,6 @@ compiled */ #include #include #include -#include -#include #include #ifdef HAVE_SYS_PRCTL_H @@ -200,6 +188,7 @@ compiled */ #include #include #include +#include #include #include #include diff --git a/daemon/sources.cmake b/daemon/sources.cmake new file mode 100644 index 000000000..8f764e46b --- /dev/null +++ b/daemon/sources.cmake @@ -0,0 +1,105 @@ +set(SRC + ${CMAKE_SOURCE_DIR}/daemon/connect/Connection.cpp + ${CMAKE_SOURCE_DIR}/daemon/connect/TlsSocket.cpp + ${CMAKE_SOURCE_DIR}/daemon/connect/WebDownloader.cpp + + ${CMAKE_SOURCE_DIR}/daemon/extension/CommandScript.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/FeedScript.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/NzbScript.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/PostScript.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/PostScript.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/QueueScript.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/ScanScript.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/SchedulerScript.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/ScriptConfig.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/ScriptConfig.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/Extension.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/ExtensionLoader.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/ExtensionManager.cpp + ${CMAKE_SOURCE_DIR}/daemon/extension/ManifestFile.cpp + + ${CMAKE_SOURCE_DIR}/daemon/feed/FeedCoordinator.cpp + ${CMAKE_SOURCE_DIR}/daemon/feed/FeedFile.cpp + ${CMAKE_SOURCE_DIR}/daemon/feed/FeedFilter.cpp + ${CMAKE_SOURCE_DIR}/daemon/feed/FeedInfo.cpp + + ${CMAKE_SOURCE_DIR}/daemon/frontend/ColoredFrontend.cpp + ${CMAKE_SOURCE_DIR}/daemon/frontend/Frontend.cpp + ${CMAKE_SOURCE_DIR}/daemon/frontend/LoggableFrontend.cpp + ${CMAKE_SOURCE_DIR}/daemon/frontend/NCursesFrontend.cpp + + ${CMAKE_SOURCE_DIR}/daemon/main/CommandLineParser.cpp + ${CMAKE_SOURCE_DIR}/daemon/main/DiskService.cpp + ${CMAKE_SOURCE_DIR}/daemon/main/Maintenance.cpp + ${CMAKE_SOURCE_DIR}/daemon/main/nzbget.cpp + ${CMAKE_SOURCE_DIR}/daemon/main/Options.cpp + ${CMAKE_SOURCE_DIR}/daemon/main/Scheduler.cpp + ${CMAKE_SOURCE_DIR}/daemon/main/StackTrace.cpp + ${CMAKE_SOURCE_DIR}/daemon/main/WorkState.cpp + + ${CMAKE_SOURCE_DIR}/daemon/nntp/ArticleDownloader.cpp + ${CMAKE_SOURCE_DIR}/daemon/nntp/ArticleWriter.cpp + ${CMAKE_SOURCE_DIR}/daemon/nntp/Decoder.cpp + ${CMAKE_SOURCE_DIR}/daemon/nntp/NewsServer.cpp + ${CMAKE_SOURCE_DIR}/daemon/nntp/NntpConnection.cpp + ${CMAKE_SOURCE_DIR}/daemon/nntp/ServerPool.cpp + ${CMAKE_SOURCE_DIR}/daemon/nntp/StatMeter.cpp + + ${CMAKE_SOURCE_DIR}/daemon/nserv/NntpServer.cpp + ${CMAKE_SOURCE_DIR}/daemon/nserv/NServFrontend.cpp + ${CMAKE_SOURCE_DIR}/daemon/nserv/NServMain.cpp + ${CMAKE_SOURCE_DIR}/daemon/nserv/NzbGenerator.cpp + ${CMAKE_SOURCE_DIR}/daemon/nserv/YEncoder.cpp + + ${CMAKE_SOURCE_DIR}/daemon/postprocess/Cleanup.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/DirectUnpack.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/DupeMatcher.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/ParChecker.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/ParParser.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/ParRenamer.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/PrePostProcessor.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/RarReader.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/RarRenamer.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/Rename.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/Repair.cpp + ${CMAKE_SOURCE_DIR}/daemon/postprocess/Unpack.cpp + + ${CMAKE_SOURCE_DIR}/daemon/queue/DirectRenamer.cpp + ${CMAKE_SOURCE_DIR}/daemon/queue/DiskState.cpp + ${CMAKE_SOURCE_DIR}/daemon/queue/DownloadInfo.cpp + ${CMAKE_SOURCE_DIR}/daemon/queue/DupeCoordinator.cpp + ${CMAKE_SOURCE_DIR}/daemon/queue/HistoryCoordinator.cpp + ${CMAKE_SOURCE_DIR}/daemon/queue/NzbFile.cpp + ${CMAKE_SOURCE_DIR}/daemon/queue/QueueCoordinator.cpp + ${CMAKE_SOURCE_DIR}/daemon/queue/QueueEditor.cpp + ${CMAKE_SOURCE_DIR}/daemon/queue/Scanner.cpp + ${CMAKE_SOURCE_DIR}/daemon/queue/UrlCoordinator.cpp + + ${CMAKE_SOURCE_DIR}/daemon/remote/BinRpc.cpp + ${CMAKE_SOURCE_DIR}/daemon/remote/RemoteClient.cpp + ${CMAKE_SOURCE_DIR}/daemon/remote/RemoteServer.cpp + ${CMAKE_SOURCE_DIR}/daemon/remote/WebServer.cpp + ${CMAKE_SOURCE_DIR}/daemon/remote/XmlRpc.cpp + ${CMAKE_SOURCE_DIR}/daemon/remote/MessageBase.h + + ${CMAKE_SOURCE_DIR}/daemon/util/FileSystem.cpp + ${CMAKE_SOURCE_DIR}/daemon/util/Log.cpp + ${CMAKE_SOURCE_DIR}/daemon/util/NString.cpp + ${CMAKE_SOURCE_DIR}/daemon/util/Observer.cpp + ${CMAKE_SOURCE_DIR}/daemon/util/ScriptController.cpp + ${CMAKE_SOURCE_DIR}/daemon/util/Service.cpp + ${CMAKE_SOURCE_DIR}/daemon/util/Thread.cpp + ${CMAKE_SOURCE_DIR}/daemon/util/Util.cpp + ${CMAKE_SOURCE_DIR}/daemon/util/Json.cpp + ${CMAKE_SOURCE_DIR}/daemon/util/Xml.cpp +) + +set(WIN32_SRC + ${CMAKE_SOURCE_DIR}/daemon/windows/StdAfx.cpp + ${CMAKE_SOURCE_DIR}/daemon/windows/WinConsole.cpp + ${CMAKE_SOURCE_DIR}/daemon/windows/WinService.cpp +) + +if(WIN32) + set(SRC ${SRC} ${WIN32_SRC}) +endif() diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt deleted file mode 100644 index c879cc887..000000000 --- a/lib/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -add_library(Yencode STATIC - ${CMAKE_CURRENT_SOURCE_DIR}/yencode/SimdInit.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/yencode/SimdDecoder.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/yencode/ScalarDecoder.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/yencode/Sse2Decoder.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/yencode/Ssse3Decoder.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/yencode/PclmulCrc.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/yencode/NeonDecoder.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/yencode/AcleCrc.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/yencode/SliceCrc.cpp -) -target_include_directories(Yencode PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/yencode - ${CMAKE_SOURCE_DIR}/daemon/main - ${ZLIB_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIR} -) - -add_library(Par2 STATIC - ${CMAKE_CURRENT_SOURCE_DIR}/par2/commandline.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/crc.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/creatorpacket.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/criticalpacket.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/datablock.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/descriptionpacket.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/diskfile.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/filechecksummer.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/galois.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/mainpacket.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/md5.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/par2fileformat.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/par2repairer.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/par2repairersourcefile.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/parheaders.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/recoverypacket.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/reedsolomon.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/verificationhashtable.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/par2/verificationpacket.cpp -) -target_include_directories(Par2 PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/par2 - ${CMAKE_SOURCE_DIR}/daemon/main - ${CMAKE_SOURCE_DIR}/daemon/util - ${OPENSSL_INCLUDE_DIR} -) diff --git a/lib/regex/regex.c b/lib/regex/regex.c index f30a6aec9..0242bea30 100644 --- a/lib/regex/regex.c +++ b/lib/regex/regex.c @@ -17,7 +17,7 @@ License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -//#include "nzbget.h" + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -52,15 +52,17 @@ # include "../locale/localeinfo.h" #endif -#define strncasecmp strnicmp -#define strcasecmp stricmp +#define strncasecmp strncmp +#define strcasecmp strcmp /* On some systems, limits.h sets RE_DUP_MAX to a lower value than GNU regex allows. Include it before , which correctly #undefs RE_DUP_MAX and sets it to the right value. */ #include -#include #include +#ifdef WIN32 +#include +#endif //#ifdef __cplusplus //extern "C" { diff --git a/lib/regex/regex.h b/lib/regex/regex.h index 38e7d031e..f1e085725 100644 --- a/lib/regex/regex.h +++ b/lib/regex/regex.h @@ -19,12 +19,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -//#ifndef _REGEX_H -//#define _REGEX_H 1 + #pragma once #include - /* Allow the use in C++ code. */ #ifdef __cplusplus extern "C" { diff --git a/lib/sources.cmake b/lib/sources.cmake new file mode 100644 index 000000000..45cc45fa7 --- /dev/null +++ b/lib/sources.cmake @@ -0,0 +1,98 @@ +if(CMAKE_SYSTEM_PROCESSOR MATCHES "i?86|x86_64") + set(SSE2_CXXFLAGS "-msse2") + set(SSSE3_CXXFLAGS "-mssse3") + set(PCLMUL_CXXFLAGS "-msse4.1 -mpclmul") +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm.*") + set(NEON_CXXFLAGS "-mfpu=neon") + set(ACLECRC_CXXFLAGS "-march=armv8-a+crc -fpermissive") +elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") + set(ACLECRC_CXXFLAGS "-march=armv8-a+crc -fpermissive") +endif() + +add_library(regex STATIC + ${CMAKE_SOURCE_DIR}/lib/regex/regex.c +) +target_include_directories(regex PUBLIC + ${CMAKE_SOURCE_DIR}/lib/regex +) + +add_library(yencode STATIC + ${CMAKE_SOURCE_DIR}/lib/yencode/SimdInit.cpp + ${CMAKE_SOURCE_DIR}/lib/yencode/SimdDecoder.cpp + ${CMAKE_SOURCE_DIR}/lib/yencode/ScalarDecoder.cpp + ${CMAKE_SOURCE_DIR}/lib/yencode/Sse2Decoder.cpp + ${CMAKE_SOURCE_DIR}/lib/yencode/Ssse3Decoder.cpp + ${CMAKE_SOURCE_DIR}/lib/yencode/PclmulCrc.cpp + ${CMAKE_SOURCE_DIR}/lib/yencode/NeonDecoder.cpp + ${CMAKE_SOURCE_DIR}/lib/yencode/AcleCrc.cpp + ${CMAKE_SOURCE_DIR}/lib/yencode/SliceCrc.cpp +) +target_include_directories(yencode PUBLIC + ${CMAKE_SOURCE_DIR}/lib/yencode + ${CMAKE_SOURCE_DIR}/lib/regex + ${CMAKE_SOURCE_DIR}/daemon/main + ${INCLUDES} +) + +set_source_files_properties( + ${CMAKE_SOURCE_DIR}/lib/yencode/Sse2Decoder.cpp + PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${SSE2_CXXFLAGS}" +) + +set_source_files_properties( + ${CMAKE_SOURCE_DIR}/lib/yencode/Ssse3Decoder.cpp + PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${SSSE3_CXXFLAGS}" +) + +set_source_files_properties( + ${CMAKE_SOURCE_DIR}/lib/yencode/PclmulCrc.cpp + PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${PCLMUL_CXXFLAGS}" +) + +set_source_files_properties( + ${CMAKE_SOURCE_DIR}/lib/yencode/NeonDecoder.cpp + PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS_RELEASE} ${NEON_CXXFLAGS}" +) + +set_source_files_properties( + ${CMAKE_SOURCE_DIR}/lib/yencode/AcleCrc.cpp + PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${ACLECRC_CXXFLAGS}" +) + +if(NOT DISABLE_PARCHECK) + add_library(par2 STATIC + ${CMAKE_SOURCE_DIR}/lib/par2/commandline.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/crc.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/creatorpacket.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/criticalpacket.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/datablock.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/descriptionpacket.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/diskfile.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/filechecksummer.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/galois.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/mainpacket.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/md5.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/par2fileformat.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/par2repairer.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/par2repairersourcefile.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/parheaders.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/recoverypacket.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/reedsolomon.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/verificationhashtable.cpp + ${CMAKE_SOURCE_DIR}/lib/par2/verificationpacket.cpp + ) + target_include_directories(par2 PUBLIC + ${CMAKE_SOURCE_DIR}/lib/par2 + ${CMAKE_SOURCE_DIR}/lib/regex + ${CMAKE_SOURCE_DIR}/daemon/main + ${CMAKE_SOURCE_DIR}/daemon/util + ${INCLUDES} + ) +endif() + +set(LIBS ${LIBS} regex yencode) +set(INCLUDES ${INCLUDES} ${CMAKE_SOURCE_DIR}/lib/regex ${CMAKE_SOURCE_DIR}/lib/yencode) +if(NOT DISABLE_PARCHECK) + set(LIBS ${LIBS} par2) + set(INCLUDES ${INCLUDES} ${CMAKE_SOURCE_DIR}/lib/par2) +endif() diff --git a/tests/extension/CMakeLists.txt b/tests/extension/CMakeLists.txt index fa52c78fe..447c151c2 100644 --- a/tests/extension/CMakeLists.txt +++ b/tests/extension/CMakeLists.txt @@ -29,16 +29,10 @@ file(GLOB ExtensionSrc ${CMAKE_SOURCE_DIR}/daemon/connect/WebDownloader.cpp ${CMAKE_SOURCE_DIR}/daemon/connect/Connection.cpp ${CMAKE_SOURCE_DIR}/daemon/connect/TlsSocket.cpp - ${CMAKE_SOURCE_DIR}/lib/regex/regex.c ) add_executable(ExtensionTests ${ExtensionSrc}) -target_link_libraries(ExtensionTests PRIVATE - ZLIB::ZLIB - Yencode - OpenSSL::SSL - ${LIBXML2_LIBRARIES} -) +target_link_libraries(ExtensionTests PRIVATE ${LIBS}) target_include_directories(ExtensionTests PRIVATE ${CMAKE_SOURCE_DIR}/daemon/main @@ -52,9 +46,7 @@ target_include_directories(ExtensionTests PRIVATE ${CMAKE_SOURCE_DIR}/daemon/connect ${CMAKE_SOURCE_DIR}/lib/regex ${CMAKE_SOURCE_DIR}/lib/yencode - ${ZLIB_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} + ${INCLUDES} ) file(COPY ../testdata/extension/manifest DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/tests/feed/CMakeLists.txt b/tests/feed/CMakeLists.txt index 2620cf141..0fd38c944 100644 --- a/tests/feed/CMakeLists.txt +++ b/tests/feed/CMakeLists.txt @@ -13,13 +13,8 @@ add_executable(FeedTest ${CMAKE_SOURCE_DIR}/daemon/queue/DownloadInfo.cpp ${CMAKE_SOURCE_DIR}/daemon/queue/DiskState.cpp ${CMAKE_SOURCE_DIR}/daemon/nntp/NewsServer.cpp - ${CMAKE_SOURCE_DIR}/lib/regex/regex.c -) -target_link_libraries(FeedTest PRIVATE - ZLIB::ZLIB - Yencode - LibXml2::LibXml2 ) +target_link_libraries(FeedTest PRIVATE ${LIBS}) target_include_directories(FeedTest PRIVATE ${CMAKE_SOURCE_DIR}/daemon/feed ${CMAKE_SOURCE_DIR}/daemon/main @@ -28,8 +23,7 @@ target_include_directories(FeedTest PRIVATE ${CMAKE_SOURCE_DIR}/daemon/nntp ${CMAKE_SOURCE_DIR}/daemon/remote ${CMAKE_SOURCE_DIR}/lib/regex - ${Boost_INCLUDE_DIR} - ${LIBXML2_INCLUDE_DIR} + ${INCLUDES} ) file(COPY ../testdata/feed DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/tests/feed/FeedFileTest.cpp b/tests/feed/FeedFileTest.cpp index 5375f1fc3..c5fce143d 100644 --- a/tests/feed/FeedFileTest.cpp +++ b/tests/feed/FeedFileTest.cpp @@ -21,12 +21,12 @@ #include -#include +#include "FileSystem.h" #include "FeedFile.h" BOOST_AUTO_TEST_CASE(FeedFileTest) { - std::string path = std::filesystem::current_path().string(); + std::string path = FileSystem::GetCurrentDirectory().Str(); std::string testFile = path + "/feed/feed.xml"; FeedFile file(testFile.c_str(), "feedName"); diff --git a/tests/main/CMakeLists.txt b/tests/main/CMakeLists.txt index c38b58b74..4cab2dd56 100644 --- a/tests/main/CMakeLists.txt +++ b/tests/main/CMakeLists.txt @@ -12,13 +12,8 @@ add_executable(MainTests ${CMAKE_SOURCE_DIR}/daemon/queue/DownloadInfo.cpp ${CMAKE_SOURCE_DIR}/daemon/feed/FeedInfo.cpp ${CMAKE_SOURCE_DIR}/daemon/nntp/NewsServer.cpp - ${CMAKE_SOURCE_DIR}/lib/regex/regex.c -) -target_link_libraries(MainTests PRIVATE - ZLIB::ZLIB - Yencode - LibXml2::LibXml2 ) +target_link_libraries(MainTests PRIVATE ${LIBS}) target_include_directories(MainTests PRIVATE ${CMAKE_SOURCE_DIR}/daemon/main ${CMAKE_SOURCE_DIR}/daemon/util @@ -28,9 +23,7 @@ target_include_directories(MainTests PRIVATE ${CMAKE_SOURCE_DIR}/daemon/nntp ${CMAKE_SOURCE_DIR}/lib/yencode ${CMAKE_SOURCE_DIR}/lib/regex - ${OPENSSL_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} - ${LIBXML2_INCLUDE_DIR} + ${INCLUDES} ) add_test(NAME MainTests COMMAND $ --log_level=message) diff --git a/tests/nntp/CMakeLists.txt b/tests/nntp/CMakeLists.txt index 5c06ecc5d..9089edd35 100644 --- a/tests/nntp/CMakeLists.txt +++ b/tests/nntp/CMakeLists.txt @@ -13,15 +13,8 @@ add_executable(ServerPoolTest ${CMAKE_SOURCE_DIR}/daemon/feed/FeedInfo.cpp ${CMAKE_SOURCE_DIR}/daemon/connect/Connection.cpp ${CMAKE_SOURCE_DIR}/daemon/connect/TlsSocket.cpp - ${CMAKE_SOURCE_DIR}/lib/regex/regex.c -) -target_link_libraries(ServerPoolTest PRIVATE - OpenSSL::SSL - ZLIB::ZLIB - Par2 - Yencode - LibXml2::LibXml2 ) +target_link_libraries(ServerPoolTest PRIVATE ${LIBS}) target_include_directories(ServerPoolTest PRIVATE ${CMAKE_SOURCE_DIR}/daemon/main ${CMAKE_SOURCE_DIR}/daemon/nntp @@ -32,9 +25,7 @@ target_include_directories(ServerPoolTest PRIVATE ${CMAKE_SOURCE_DIR}/daemon/remote ${CMAKE_SOURCE_DIR}/lib/yencode ${CMAKE_SOURCE_DIR}/lib/par2 - ${OPENSSL_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} - ${LIBXML2_INCLUDE_DIR} + ${INCLUDES} ) add_test(NAME ServerPoolTest COMMAND $ --log_level=message) diff --git a/tests/nntp/ServerPoolTest.cpp b/tests/nntp/ServerPoolTest.cpp index d7eb7ca59..d728472fc 100644 --- a/tests/nntp/ServerPoolTest.cpp +++ b/tests/nntp/ServerPoolTest.cpp @@ -214,7 +214,7 @@ BOOST_AUTO_TEST_CASE(ActiveOnOffTest) BOOST_CHECK(con3 == nullptr); } -BOOST_AUTO_TEST_CASE(IgnoreServers) +BOOST_AUTO_TEST_CASE(IgnoreServersTest) { ServerPool pool; AddTestServer(&pool, 1, true, 0, false, 0, 2); @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(IgnoreServers) BOOST_CHECK(con4 == nullptr); } -BOOST_AUTO_TEST_CASE(IgnoreServersGrouped) +BOOST_AUTO_TEST_CASE(IgnoreServersGroupedTest) { ServerPool pool; AddTestServer(&pool, 1, true, 0, false, 1, 2); @@ -267,17 +267,17 @@ BOOST_AUTO_TEST_CASE(IgnoreServersGrouped) BOOST_CHECK(con3 == nullptr); } -BOOST_AUTO_TEST_CASE(BlockServersUngrouped) +BOOST_AUTO_TEST_CASE(BlockServersUngroupedTest) { TestBlockServers(0); } -BOOST_AUTO_TEST_CASE(BlockServersGrouped) +BOOST_AUTO_TEST_CASE(BlockServersGroupedTest) { TestBlockServers(1); } -BOOST_AUTO_TEST_CASE(BlockOptionalServersUngrouped) +BOOST_AUTO_TEST_CASE(BlockOptionalServersUngroupedTest) { TestOptionalBlockServers(0); } @@ -287,12 +287,12 @@ BOOST_AUTO_TEST_CASE(BlockOptionalServersGrouped) TestOptionalBlockServers(1); } -BOOST_AUTO_TEST_CASE(BlockOptionalAndNonOptionalServersUngrouped) +BOOST_AUTO_TEST_CASE(BlockOptionalAndNonOptionalServersUngroupedTest) { TestBlockOptionalAndNonOptionalServers(0); } -BOOST_AUTO_TEST_CASE(BlockOptionalAndNonOptionalServersGrouped) +BOOST_AUTO_TEST_CASE(BlockOptionalAndNonOptionalServersGroupedTest) { TestBlockOptionalAndNonOptionalServers(1); } diff --git a/tests/postprocess/CMakeLists.txt b/tests/postprocess/CMakeLists.txt index 398b994fc..5189f8788 100644 --- a/tests/postprocess/CMakeLists.txt +++ b/tests/postprocess/CMakeLists.txt @@ -24,18 +24,10 @@ file(GLOB PostprocessTestsSrc ${CMAKE_SOURCE_DIR}/daemon/util/FileSystem.cpp ${CMAKE_SOURCE_DIR}/daemon/queue/DownloadInfo.cpp ${CMAKE_SOURCE_DIR}/daemon/queue/DiskState.cpp - ${CMAKE_SOURCE_DIR}/lib/regex/regex.c ) add_executable(PostprocessTests ${PostprocessTestsSrc}) -target_link_libraries(PostprocessTests PRIVATE - ZLIB::ZLIB - Yencode - Par2 - OpenSSL::SSL - OpenSSL::Crypto - LibXml2::LibXml2 -) +target_link_libraries(PostprocessTests PRIVATE ${LIBS}) target_include_directories(PostprocessTests PRIVATE ../suite ${CMAKE_SOURCE_DIR}/daemon/main @@ -48,8 +40,7 @@ target_include_directories(PostprocessTests PRIVATE ${CMAKE_SOURCE_DIR}/daemon/nntp ${CMAKE_SOURCE_DIR}/lib/yencode ${CMAKE_SOURCE_DIR}/lib/par2 - ${Boost_INCLUDE_DIR} - ${LIBXML2_INCLUDE_DIR} + ${INCLUDES} ) file(COPY ../testdata/rarrenamer DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/tests/postprocess/DirectUnpackTest.cpp b/tests/postprocess/DirectUnpackTest.cpp index 3e913fa08..b8234481c 100644 --- a/tests/postprocess/DirectUnpackTest.cpp +++ b/tests/postprocess/DirectUnpackTest.cpp @@ -21,13 +21,21 @@ #include "nzbget.h" #include -#include +#include "FileSystem.h" #include "DirectUnpack.h" #include "Log.h" #include "Options.h" #include "DiskState.h" +Log* g_Log = new Log(); +Options* g_Options; +DiskState* g_DiskState; + +char* envVars[] = {"NZBXX_YYYY", 0}; +char* (*g_EnvironmentVariables)[2] = &envVars; +char* (*g_Arguments)[] = nullptr; + class DirectUnpackDownloadQueueMock : public DownloadQueue { public: @@ -51,24 +59,32 @@ BOOST_AUTO_TEST_CASE(DirectUnpackSimpleTest) BOOST_TEST_MESSAGE("This test requires working unrar 5 in search path"); - const std::string testDataDir = std::filesystem::current_path().string() + "/rarrenamer"; - const std::string workingDir = testDataDir + "/empty"; - std::filesystem::create_directory(workingDir); + std::string currDir = FileSystem::GetCurrentDirectory().Str(); + std::string testDataDir = currDir + "/rarrenamer"; + std::string workingDir = testDataDir + "/empty"; + + BOOST_REQUIRE(FileSystem::CreateDirectory(workingDir.c_str())); - std::filesystem::copy( - (testDataDir + "/testfile3.part01.rar").c_str(), - (workingDir + "/testfile3.part01.rar").c_str() + BOOST_REQUIRE( + FileSystem::CopyFile( + (testDataDir + "/testfile3.part01.rar").c_str(), + (workingDir + "/testfile3.part01.rar").c_str() + ) ); - std::filesystem::copy( - (testDataDir + "/testfile3.part02.rar").c_str(), - (workingDir + "/testfile3.part02.rar").c_str() + BOOST_REQUIRE( + FileSystem::CopyFile( + (testDataDir + "/testfile3.part02.rar").c_str(), + (workingDir + "/testfile3.part02.rar").c_str() + ) ); - std::filesystem::copy( - (testDataDir + "/testfile3.part03.rar").c_str(), - (workingDir + "/testfile3.part03.rar").c_str() + BOOST_REQUIRE( + FileSystem::CopyFile( + (testDataDir + "/testfile3.part03.rar").c_str(), + (workingDir + "/testfile3.part03.rar").c_str() + ) ); - + std::unique_ptr nzbInfo = std::make_unique(); NzbInfo* nzbPtr = nzbInfo.get(); nzbInfo->SetName("test"); @@ -94,8 +110,8 @@ BOOST_AUTO_TEST_CASE(DirectUnpackSimpleTest) } BOOST_CHECK(nzbPtr->GetDirectUnpackStatus() == NzbInfo::nsSuccess); - BOOST_CHECK(std::filesystem::exists((workingDir + "/_unpack/testfile3.dat").c_str())); - std::filesystem::remove_all(workingDir); + BOOST_CHECK(FileSystem::FileExists((workingDir + "/_unpack/testfile3.dat").c_str())); + BOOST_REQUIRE(FileSystem::RemoveDirectory(workingDir.c_str())); } BOOST_AUTO_TEST_CASE(DirectUnpackTwoArchives) @@ -109,32 +125,34 @@ BOOST_AUTO_TEST_CASE(DirectUnpackTwoArchives) BOOST_TEST_MESSAGE("This test requires working unrar 5 in search path"); - const std::string testDataDir = std::filesystem::current_path().string() + "/testdata"; - const std::string workingDir = testDataDir + "empty"; - std::filesystem::create_directory(workingDir); + std::string currDir = FileSystem::GetCurrentDirectory().Str(); + std::string testDataDir = currDir + "/rarrenamer"; + std::string workingDir = testDataDir + "/empty"; + + BOOST_REQUIRE(FileSystem::CreateDirectory(workingDir.c_str())); - std::filesystem::copy( + FileSystem::CopyFile( (testDataDir + "/testfile3.part01.rar").c_str(), (workingDir + "/testfile3.part01.rar").c_str() ); - std::filesystem::copy( + FileSystem::CopyFile( (testDataDir + "/testfile3.part02.rar").c_str(), (workingDir + "/testfile3.part02.rar").c_str() ); - std::filesystem::copy( + FileSystem::CopyFile( (testDataDir + "/testfile3.part03.rar").c_str(), (workingDir + "/testfile3.part03.rar").c_str() ); - std::filesystem::copy( + FileSystem::CopyFile( (testDataDir + "/testfile5.part01.rar").c_str(), (workingDir + "/testfile5.part01.rar").c_str() ); - std::filesystem::copy( + FileSystem::CopyFile( (testDataDir + "/testfile5.part02.rar").c_str(), (workingDir + "/testfile5.part02.rar").c_str() ); - std::filesystem::copy( + FileSystem::CopyFile( (testDataDir + "/testfile5.part03.rar").c_str(), (workingDir + "/testfile5.part03.rar").c_str() ); @@ -164,7 +182,7 @@ BOOST_AUTO_TEST_CASE(DirectUnpackTwoArchives) } BOOST_CHECK(nzbPtr->GetDirectUnpackStatus() == NzbInfo::nsSuccess); - BOOST_CHECK(std::filesystem::exists((workingDir + "/_unpack/testfile3.dat").c_str())); - BOOST_CHECK(std::filesystem::exists((workingDir + "/_unpack/testfile5.dat").c_str())); - std::filesystem::remove_all(workingDir); + BOOST_CHECK(FileSystem::FileExists((workingDir + "/_unpack/testfile3.dat").c_str())); + BOOST_CHECK(FileSystem::FileExists((workingDir + "/_unpack/testfile5.dat").c_str())); + BOOST_REQUIRE(FileSystem::RemoveDirectory(workingDir.c_str())); } diff --git a/tests/queue/CMakeLists.txt b/tests/queue/CMakeLists.txt index bb535efd5..b1952ee0e 100644 --- a/tests/queue/CMakeLists.txt +++ b/tests/queue/CMakeLists.txt @@ -11,13 +11,8 @@ add_executable(NzbFileTest ${CMAKE_SOURCE_DIR}/daemon/util/NString.cpp ${CMAKE_SOURCE_DIR}/daemon/util/Log.cpp ${CMAKE_SOURCE_DIR}/daemon/nntp/NewsServer.cpp - ${CMAKE_SOURCE_DIR}/lib/regex/regex.c -) -target_link_libraries(NzbFileTest PRIVATE - ZLIB::ZLIB - Yencode - LibXml2::LibXml2 ) +target_link_libraries(NzbFileTest PRIVATE ${LIBS}) target_include_directories(NzbFileTest PRIVATE ${CMAKE_SOURCE_DIR}/daemon/main ${CMAKE_SOURCE_DIR}/daemon/util @@ -26,9 +21,7 @@ target_include_directories(NzbFileTest PRIVATE ${CMAKE_SOURCE_DIR}/daemon/remote ${CMAKE_SOURCE_DIR}/daemon/nntp ${CMAKE_SOURCE_DIR}/lib/yencode - ${OPENSSL_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} - ${LIBXML2_INCLUDE_DIR} + ${INCLUDES} ) file(COPY ../testdata/nzbfile DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/tests/queue/NzbFileTest.cpp b/tests/queue/NzbFileTest.cpp index b5a1771f1..ce119f9f2 100644 --- a/tests/queue/NzbFileTest.cpp +++ b/tests/queue/NzbFileTest.cpp @@ -23,12 +23,11 @@ #define BOOST_TEST_MODULE "NzbFileTest" #include -#include - #include "NzbFile.h" #include "Log.h" #include "Options.h" #include "DiskState.h" +#include "FileSystem.h" Log* g_Log; Options* g_Options; @@ -36,9 +35,7 @@ DiskState* g_DiskState; void TestNzb(std::string testFilename) { - BOOST_TEST_MESSAGE(std::string("Filename: ") + testFilename); - - std::string path = std::filesystem::current_path().string(); + std::string path = FileSystem::GetCurrentDirectory().Str(); std::string nzbFilename(path + "/nzbfile/" + testFilename + ".nzb"); std::string infoFilename(path + "/nzbfile/" + testFilename + ".txt"); @@ -73,7 +70,7 @@ void TestNzb(std::string testFilename) xmlCleanupParser(); } -BOOST_AUTO_TEST_CASE(NZBParser) +BOOST_AUTO_TEST_CASE(NZBParserTest) { Options::CmdOptList cmdOpts; Options options(&cmdOpts, nullptr); diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt index 480719680..bff0dbd18 100644 --- a/tests/util/CMakeLists.txt +++ b/tests/util/CMakeLists.txt @@ -9,25 +9,11 @@ file(GLOB UtilTestSrc ${CMAKE_SOURCE_DIR}/daemon/util/Util.cpp ${CMAKE_SOURCE_DIR}/daemon/util/Json.cpp ${CMAKE_SOURCE_DIR}/daemon/util/Xml.cpp - ${CMAKE_SOURCE_DIR}/lib/regex/regex.c ) add_executable(UtilTests ${UtilTestSrc}) -target_link_libraries(UtilTests PRIVATE - ZLIB::ZLIB - Yencode - LibXml2::LibXml2 -) +target_link_libraries(UtilTests PRIVATE ${LIBS}) -target_include_directories(UtilTests PRIVATE - ${CMAKE_SOURCE_DIR}/daemon/main - ${CMAKE_SOURCE_DIR}/daemon/util - ${CMAKE_SOURCE_DIR}/lib/regex - ${CMAKE_SOURCE_DIR}/lib/yencode - ${ZLIB_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} - ${LIBXML2_INCLUDE_DIR} -) +target_include_directories(UtilTests PRIVATE ${INCLUDES}) add_test(NAME UtilTests COMMAND $ --log_level=message) From f273f7e2d0922383ed99d63c7ab3853955c18685 Mon Sep 17 00:00:00 2001 From: Denis <146707790+dnzbk@users.noreply.github.com> Date: Wed, 6 Mar 2024 01:52:13 -0800 Subject: [PATCH 16/42] CMake fixies (#192) --- CMakeLists.txt | 6 ++---- cmake/posix.cmake | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 556ff66c6..c455a8880 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,9 +40,8 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "-O0 -g0 -pthread -g -Wall -Wextra" CACHE STRING "" FORCE) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - set(CMAKE_CXX_FLAGS "/Od /Zi /MP /W4 /EHs /DDEBUG /D_DEBUG /DWIN32 /wd4800 /wd4267" CACHE STRING "" FORCE) + set(CMAKE_CXX_FLAGS "/Od /Zi /MTd /MP /W4 /EHs /DDEBUG /D_DEBUG /DWIN32 /wd4800 /wd4267" CACHE STRING "" FORCE) set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} winmm.lib Dbghelp.lib libcpmtd.lib" CACHE STRING "" FORCE) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebug" CACHE STRING "" FORCE) endif() elseif(CMAKE_BUILD_TYPE STREQUAL "Release") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") @@ -52,9 +51,8 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Release") set(CMAKE_CXX_FLAGS "-O2 -g0 -pthread -DNDEBUG -Wall -Wextra" CACHE STRING "" FORCE) set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" CACHE STRING "" FORCE) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - set(CMAKE_CXX_FLAGS "/O2 /MP /W4 /EHs /DNDEBUG /DWIN32 /wd4800 /wd4267" CACHE STRING "" FORCE) + set(CMAKE_CXX_FLAGS "/O2 /MT /MP /W4 /EHs /DNDEBUG /DWIN32 /wd4800 /wd4267" CACHE STRING "" FORCE) set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} winmm.lib" CACHE STRING "" FORCE) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded" CACHE STRING "" FORCE) endif() endif() diff --git a/cmake/posix.cmake b/cmake/posix.cmake index 376d92ea1..ff46d04e2 100644 --- a/cmake/posix.cmake +++ b/cmake/posix.cmake @@ -285,6 +285,8 @@ check_cxx_source_compiles(" # Check TLS/SSL if(USE_OPENSSL AND NOT ENABLE_STATIC) check_library_exists(OpenSSL::Crypto X509_check_host "" HAVE_X509_CHECK_HOST) +elseif(USE_OPENSSL AND ENABLE_STATIC) + set(HAVE_X509_CHECK_HOST 1) endif() check_cxx_source_compiles(" From e104151521d44b769beb47db3f282d9ec4f1eb2d Mon Sep 17 00:00:00 2001 From: Denis <146707790+dnzbk@users.noreply.github.com> Date: Wed, 6 Mar 2024 23:02:58 -0800 Subject: [PATCH 17/42] Fix/v1 extension loader (#193) ## Description Added: - additional checks that "select options" are at the end of the string line; - more unit tests; ## Testing By @dnzbk with all available extensions in the Extension manager + NotifyPlex; --- daemon/extension/ExtensionLoader.cpp | 13 +++++++++---- tests/extension/ExtensionLoaderTest.cpp | 24 ++++++++++++++++++++++-- tests/testdata/extension/V1/Extension.py | 10 ++++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/daemon/extension/ExtensionLoader.cpp b/daemon/extension/ExtensionLoader.cpp index c5135f7a4..72317b107 100644 --- a/daemon/extension/ExtensionLoader.cpp +++ b/daemon/extension/ExtensionLoader.cpp @@ -226,11 +226,11 @@ namespace ExtensionLoader size_t selectStartIdx = line.rfind("("); size_t selectEndIdx = line.rfind(")"); - bool hasSelectOptions = selectStartIdx != std::string::npos - && description.empty() + bool hasSelectOptions = description.empty() + && !strncmp(line.c_str(), "# ", 2) + && selectStartIdx != std::string::npos && selectEndIdx != std::string::npos - && selectEndIdx != std::string::npos - && !strncmp(line.c_str(), "# ", 2); + && selectEndIdx == line.length() - 2; // e.g. # Description (Always, OnFailure) or # Description (1-65535) or # Description (1, 2-5, 10). if (hasSelectOptions) @@ -411,6 +411,11 @@ namespace ExtensionLoader word += str[i]; } + if (elements.size() == 1) + { + return std::make_pair(std::move(elements), ""); + } + return std::make_pair(std::move(elements), ","); } } diff --git a/tests/extension/ExtensionLoaderTest.cpp b/tests/extension/ExtensionLoaderTest.cpp index e48bc6d2e..a495e5d6b 100644 --- a/tests/extension/ExtensionLoaderTest.cpp +++ b/tests/extension/ExtensionLoaderTest.cpp @@ -79,7 +79,7 @@ BOOST_AUTO_TEST_CASE(ExtensionV1LoaderTest) BOOST_CHECK(command2.action == "Send Test"); BOOST_CHECK(command2.description == std::vector({ "Test (0 1).", "description." })); - BOOST_CHECK(extension.GetOptions().size() == 14); + BOOST_CHECK(extension.GetOptions().size() == 16); auto option = extension.GetOptions()[0]; @@ -220,6 +220,26 @@ BOOST_AUTO_TEST_CASE(ExtensionV1LoaderTest) "ionice scheduling class.", "Set the ionice scheduling class (0, 1, 2, 3)." })); - BOOST_CHECK(boost::variant2::get(option13.value) == "2"); + BOOST_CHECK(boost::variant2::get(option14.value) == "2"); BOOST_CHECK(option14.select.empty()); + + auto option15 = extension.GetOptions()[14]; + BOOST_CHECK(option15.name == "customPlexSection"); + BOOST_CHECK(option15.displayName == "customPlexSection"); + BOOST_CHECK(option15.description == std::vector({ + "Custom Plex Section(s) you would like to update [Optional].", + "Section Number(s) corresponding to your Plex library (comma separated)." + })); + BOOST_CHECK(boost::variant2::get(option15.value) == ""); + BOOST_CHECK(option15.select.empty()); + + auto option16 = extension.GetOptions()[15]; + BOOST_CHECK(option16.name == "test2"); + BOOST_CHECK(option16.displayName == "test2"); + BOOST_CHECK(option16.description == std::vector({ + "(Test2).", + "description." + })); + BOOST_CHECK(boost::variant2::get(option16.value) == ""); + BOOST_CHECK(option16.select.empty()); } diff --git a/tests/testdata/extension/V1/Extension.py b/tests/testdata/extension/V1/Extension.py index 2dba2ea15..ca84e6591 100644 --- a/tests/testdata/extension/V1/Extension.py +++ b/tests/testdata/extension/V1/Extension.py @@ -88,5 +88,15 @@ # description. #Test@Send Test +# Custom Plex Section(s) you would like to update [Optional]. +# +# Section Number(s) corresponding to your Plex library (comma separated). +#customPlexSection= + +# (Test2). +# +# description. +#test2= + ### NZBGET POST-PROCESSING SCRIPT ### ############################################################################## From f84e39da8e059b31e4ba213b1f1a1286ece7af04 Mon Sep 17 00:00:00 2001 From: Denis <146707790+dnzbk@users.noreply.github.com> Date: Mon, 11 Mar 2024 09:42:15 +0300 Subject: [PATCH 18/42] Fix: compiler and cppcheck warnings (#197) ## Description - removed unnecessary empty namespaces; - use std::string instead of custom BString due to potential memory corruption; - added the recommended & qualifier to GetExtensions method; ## Testing By @dnzbk on: - Windows 11; - Debian 12; --- daemon/extension/Extension.cpp | 25 +- daemon/extension/Extension.h | 7 +- daemon/extension/ExtensionLoader.cpp | 381 +++++++++++++------------- daemon/extension/ExtensionLoader.h | 33 +-- daemon/extension/ExtensionManager.cpp | 11 +- daemon/extension/ExtensionManager.h | 2 +- daemon/extension/ManifestFile.cpp | 251 +++++++++-------- daemon/extension/ManifestFile.h | 16 +- 8 files changed, 353 insertions(+), 373 deletions(-) diff --git a/daemon/extension/Extension.cpp b/daemon/extension/Extension.cpp index 044fbad22..e6ab2bbda 100644 --- a/daemon/extension/Extension.cpp +++ b/daemon/extension/Extension.cpp @@ -416,21 +416,18 @@ namespace Extension return result; } - namespace + void AddNewNode(xmlNodePtr rootNode, const char* name, const char* type, const char* value) { - void AddNewNode(xmlNodePtr rootNode, const char* name, const char* type, const char* value) - { - xmlNodePtr memberNode = xmlNewNode(NULL, BAD_CAST "member"); - xmlNodePtr valueNode = xmlNewNode(NULL, BAD_CAST "value"); - xmlNewChild(memberNode, NULL, BAD_CAST "name", BAD_CAST name); - xmlNewChild(valueNode, NULL, BAD_CAST type, BAD_CAST value); - xmlAddChild(memberNode, valueNode); - xmlAddChild(rootNode, memberNode); - } + xmlNodePtr memberNode = xmlNewNode(NULL, BAD_CAST "member"); + xmlNodePtr valueNode = xmlNewNode(NULL, BAD_CAST "value"); + xmlNewChild(memberNode, NULL, BAD_CAST "name", BAD_CAST name); + xmlNewChild(valueNode, NULL, BAD_CAST type, BAD_CAST value); + xmlAddChild(memberNode, valueNode); + xmlAddChild(rootNode, memberNode); + } - const char* BoolToStr(bool value) - { - return value ? "true" : "false"; - } + const char* BoolToStr(bool value) + { + return value ? "true" : "false"; } } diff --git a/daemon/extension/Extension.h b/daemon/extension/Extension.h index 6e3e7ef11..dd4f04078 100644 --- a/daemon/extension/Extension.h +++ b/daemon/extension/Extension.h @@ -107,11 +107,8 @@ namespace Extension std::string ToJsonStr(const Script& script); std::string ToXmlStr(const Script& script); - namespace - { - void AddNewNode(xmlNodePtr rootNode, const char* name, const char* type, const char* value); - const char* BoolToStr(bool value); - } + static void AddNewNode(xmlNodePtr rootNode, const char* name, const char* type, const char* value); + static const char* BoolToStr(bool value); } #endif diff --git a/daemon/extension/ExtensionLoader.cpp b/daemon/extension/ExtensionLoader.cpp index 72317b107..5ade183f8 100644 --- a/daemon/extension/ExtensionLoader.cpp +++ b/daemon/extension/ExtensionLoader.cpp @@ -181,243 +181,241 @@ namespace ExtensionLoader return true; } - namespace + + void RemoveTailAndTrim(std::string& str, const char* tail) { - void RemoveTailAndTrim(std::string& str, const char* tail) + size_t tailIdx = str.find(tail); + if (tailIdx != std::string::npos) { - size_t tailIdx = str.find(tail); - if (tailIdx != std::string::npos) - { - str.erase(tailIdx); - } - Util::TrimRight(str); + str.erase(tailIdx); } + Util::TrimRight(str); + } - void BuildDisplayName(Extension::Script& script) - { - BString<1024> shortName = script.GetName(); - if (char* ext = strrchr(shortName, '.')) *ext = '\0'; // strip file extension + void BuildDisplayName(Extension::Script& script) + { + BString<1024> shortName = script.GetName(); + if (char* ext = strrchr(shortName, '.')) *ext = '\0'; // strip file extension - const char* displayName = FileSystem::BaseFileName(shortName); + const char* displayName = FileSystem::BaseFileName(shortName); - script.SetDisplayName(displayName); - } + script.SetDisplayName(displayName); + } + + void ParseOptionsAndCommands( + std::ifstream& file, + std::vector& options, + std::vector& commands) + { + std::vector selectOpts; + std::vector description; - void ParseOptionsAndCommands( - std::ifstream& file, - std::vector& options, - std::vector& commands) + std::string line; + while (std::getline(file, line)) { - std::vector selectOpts; - std::vector description; + if (strstr(line.c_str(), END_SCRIPT_SIGNATURE)) + { + break; + } + + if (line.empty()) + { + continue; + } - std::string line; - while (std::getline(file, line)) + size_t selectStartIdx = line.rfind("("); + size_t selectEndIdx = line.rfind(")"); + bool hasSelectOptions = description.empty() + && !strncmp(line.c_str(), "# ", 2) + && selectStartIdx != std::string::npos + && selectEndIdx != std::string::npos + && selectEndIdx == line.length() - 2; + + // e.g. # Description (Always, OnFailure) or # Description (1-65535) or # Description (1, 2-5, 10). + if (hasSelectOptions) { - if (strstr(line.c_str(), END_SCRIPT_SIGNATURE)) + std::string selectOptionsStr = line.substr(selectStartIdx + 1, selectEndIdx - selectStartIdx - 1); + auto result = ExtractElements(selectOptionsStr); + auto& selectOptions = result.first; + auto& delimiter = result.second; + bool canBeNum = delimiter == "-"; + + if (delimiter.empty()) // doesn't have { - break; + description.push_back(line.substr(2)); + continue; } - if (line.empty()) + if (canBeNum) { - continue; + description.push_back(line.substr(2)); + } + else + { + description.push_back(line.substr(2, selectStartIdx - 3) + "."); } - size_t selectStartIdx = line.rfind("("); - size_t selectEndIdx = line.rfind(")"); - bool hasSelectOptions = description.empty() - && !strncmp(line.c_str(), "# ", 2) - && selectStartIdx != std::string::npos - && selectEndIdx != std::string::npos - && selectEndIdx == line.length() - 2; + selectOpts = GetSelectOptions(selectOptions, canBeNum); + continue; + } - // e.g. # Description (Always, OnFailure) or # Description (1-65535) or # Description (1, 2-5, 10). - if (hasSelectOptions) - { - std::string selectOptionsStr = line.substr(selectStartIdx + 1, selectEndIdx - selectStartIdx - 1); - auto result = ExtractElements(selectOptionsStr); - auto& selectOptions = result.first; - auto& delimiter = result.second; - bool canBeNum = delimiter == "-"; - - if (delimiter.empty()) // doesn't have - { - description.push_back(line.substr(2)); - continue; - } + if (!strncmp(line.c_str(), "# ", 2)) + { + description.push_back(line.substr(2)); + continue; + } - if (canBeNum) - { - description.push_back(line.substr(2)); - } - else - { - description.push_back(line.substr(2, selectStartIdx - 3) + "."); - } + if (strncmp(line.c_str(), "# ", 2)) + { + // if option, e.g. #ConnectionTest=Send + size_t eqPos = line.find("="); + // if command, e.g. #ConnectionTest@Send Test E-Mail + size_t atPos = line.find("@"); - selectOpts = GetSelectOptions(selectOptions, canBeNum); + if (atPos != std::string::npos && eqPos == std::string::npos) + { + ManifestFile::Command command; + std::string name = line.substr(1, atPos - 1); + std::string action = line.substr(atPos + 1); + Util::Trim(action); + Util::Trim(name); + command.action = std::move(action); + command.name = std::move(name); + command.description = std::move(description); + command.displayName = command.name; + commands.push_back(std::move(command)); + description.clear(); + selectOpts.clear(); continue; } - if (!strncmp(line.c_str(), "# ", 2)) + if (eqPos != std::string::npos) { - description.push_back(line.substr(2)); + ManifestFile::Option option; + std::string name = line.substr(1, eqPos - 1); + std::string value = line.substr(eqPos + 1); + Util::Trim(value); + Util::Trim(name); + bool canBeNum = !selectOpts.empty() && boost::variant2::get_if(&selectOpts[0]); + option.value = std::move(GetSelectOpt(value, canBeNum)); + option.name = std::move(name); + option.description = std::move(description); + option.select = std::move(selectOpts); + option.displayName = option.name; + options.push_back(std::move(option)); + description.clear(); + selectOpts.clear(); continue; } + } + } + } - if (strncmp(line.c_str(), "# ", 2)) - { - // if option, e.g. #ConnectionTest=Send - size_t eqPos = line.find("="); - // if command, e.g. #ConnectionTest@Send Test E-Mail - size_t atPos = line.find("@"); - - if (atPos != std::string::npos && eqPos == std::string::npos) - { - ManifestFile::Command command; - std::string name = line.substr(1, atPos - 1); - std::string action = line.substr(atPos + 1); - Util::Trim(action); - Util::Trim(name); - command.action = std::move(action); - command.name = std::move(name); - command.description = std::move(description); - command.displayName = command.name; - commands.push_back(std::move(command)); - description.clear(); - selectOpts.clear(); - continue; - } + std::vector + GetSelectOptions(const std::vector& opts, bool canBeNum) + { + std::vector selectOpts; - if (eqPos != std::string::npos) - { - ManifestFile::Option option; - std::string name = line.substr(1, eqPos - 1); - std::string value = line.substr(eqPos + 1); - Util::Trim(value); - Util::Trim(name); - bool canBeNum = !selectOpts.empty() && boost::variant2::get_if(&selectOpts[0]); - option.value = std::move(GetSelectOpt(value, canBeNum)); - option.name = std::move(name); - option.description = std::move(description); - option.select = std::move(selectOpts); - option.displayName = option.name; - options.push_back(std::move(option)); - description.clear(); - selectOpts.clear(); - continue; - } - } - } + for (const auto& option : opts) + { + selectOpts.push_back(GetSelectOpt(option, canBeNum)); } + return selectOpts; + } - std::vector - GetSelectOptions(const std::vector& opts, bool canBeNum) + ManifestFile::SelectOption GetSelectOpt(const std::string& val, bool canBeNum) + { + if (!canBeNum) { - std::vector selectOpts; + return ManifestFile::SelectOption(val); + } - for (const auto& option : opts) - { - selectOpts.push_back(GetSelectOpt(option, canBeNum)); - } - return selectOpts; + auto result = Util::StrToNum(val); + if (result.has_value()) + { + return ManifestFile::SelectOption(result.get()); } - ManifestFile::SelectOption GetSelectOpt(const std::string& val, bool canBeNum) + return ManifestFile::SelectOption(val); + } + + std::pair, std::string> + ExtractElements(const std::string& str) + { + std::vector elements; + std::string word; + + for (size_t i = 0; i < str.size(); ++i) { - if (!canBeNum) + if (i == (str.size() - 1)) { - return ManifestFile::SelectOption(val); + word += str[i]; + elements.push_back(std::move(word)); + break; } - auto result = Util::StrToNum(val); - if (result.has_value()) + if (str[i] == ',') { - return ManifestFile::SelectOption(result.get()); + elements.push_back(std::move(word)); + word.clear(); + continue; } - return ManifestFile::SelectOption(val); - } - - std::pair, std::string> - ExtractElements(const std::string& str) - { - std::vector elements; - std::string word; - - for (size_t i = 0; i < str.size(); ++i) + if (str[i] == ' ' && word.empty()) { - if (i == str.size() - 1) - { - word += str[i]; - elements.push_back(std::move(word)); - break; - } - - if (str[i] == ',') - { - elements.push_back(std::move(word)); - word.clear(); - continue; - } + continue; + } - if (str[i] == ' ' && word.empty()) - { - continue; - } + if (str[i] == ' ' && !word.empty()) + { + elements.clear(); + elements.push_back(str); + return std::make_pair(std::move(elements), ""); + } - if (str[i] == ' ' && !word.empty()) + if (str[i] == '-' && elements.empty()) + { + std::string restWord; + for (size_t j = i + 1; j < str.size(); ++j) { - elements.clear(); - elements.push_back(str); - return std::make_pair(std::move(elements), ""); - } + if (j >= str.size() - 1) + { + restWord += str[j]; + elements.push_back(std::move(word)); + elements.push_back(std::move(restWord)); + return std::make_pair(std::move(elements), "-"); + } - if (str[i] == '-' && elements.empty()) - { - std::string restWord; - for (size_t j = i + 1; j < str.size(); ++j) + if (str[j] == ' ') { - if (j >= str.size() - 1) - { - restWord += str[j]; - elements.push_back(std::move(word)); - elements.push_back(std::move(restWord)); - return std::make_pair(std::move(elements), "-"); - } - - if (str[j] == ' ') - { - elements.push_back(str); - return std::make_pair(std::move(elements), ""); - } - - if (str[j] == ',') - { - word += '-' + restWord; - elements.push_back(std::move(word)); - word.clear(); - i = j; - break; - } + elements.push_back(str); + return std::make_pair(std::move(elements), ""); + } - restWord += str[j]; + if (str[j] == ',') + { + word += '-' + restWord; + elements.push_back(std::move(word)); + word.clear(); + i = j; + break; } - continue; + restWord += str[j]; } - word += str[i]; + continue; } - if (elements.size() == 1) - { - return std::make_pair(std::move(elements), ""); - } + word += str[i]; + } - return std::make_pair(std::move(elements), ","); + if (elements.size() == 1) + { + return std::make_pair(std::move(elements), ""); } + + return std::make_pair(std::move(elements), ","); } } @@ -448,17 +446,14 @@ namespace ExtensionLoader return true; } - namespace + Extension::Kind GetScriptKind(const std::string& line) { - Extension::Kind GetScriptKind(const std::string& line) - { - Extension::Kind kind; - kind.post = strstr(line.c_str(), POST_SCRIPT_SIGNATURE) != nullptr; - kind.scan = strstr(line.c_str(), SCAN_SCRIPT_SIGNATURE) != nullptr; - kind.queue = strstr(line.c_str(), QUEUE_SCRIPT_SIGNATURE) != nullptr; - kind.scheduler = strstr(line.c_str(), SCHEDULER_SCRIPT_SIGNATURE) != nullptr; - kind.feed = strstr(line.c_str(), FEED_SCRIPT_SIGNATURE) != nullptr; - return kind; - } + Extension::Kind kind; + kind.post = strstr(line.c_str(), POST_SCRIPT_SIGNATURE) != nullptr; + kind.scan = strstr(line.c_str(), SCAN_SCRIPT_SIGNATURE) != nullptr; + kind.queue = strstr(line.c_str(), QUEUE_SCRIPT_SIGNATURE) != nullptr; + kind.scheduler = strstr(line.c_str(), SCHEDULER_SCRIPT_SIGNATURE) != nullptr; + kind.feed = strstr(line.c_str(), FEED_SCRIPT_SIGNATURE) != nullptr; + return kind; } } diff --git a/daemon/extension/ExtensionLoader.h b/daemon/extension/ExtensionLoader.h index 1fb504c5e..916e8c626 100644 --- a/daemon/extension/ExtensionLoader.h +++ b/daemon/extension/ExtensionLoader.h @@ -47,21 +47,19 @@ namespace ExtensionLoader namespace V1 { bool Load(Extension::Script& script, const char* location, const char* rootDir); - namespace - { - void ParseOptionsAndCommands( - std::ifstream& file, - std::vector& options, - std::vector& commands - ); - std::vector - GetSelectOptions(const std::vector& opts, bool isDashDelim); - ManifestFile::SelectOption GetSelectOpt(const std::string& val, bool canBeNum); - void RemoveTailAndTrim(std::string& str, const char* tail); - void BuildDisplayName(Extension::Script& script); - std::pair, std::string> - ExtractElements(const std::string& str); - } + + static void ParseOptionsAndCommands( + std::ifstream& file, + std::vector& options, + std::vector& commands + ); + static std::vector + GetSelectOptions(const std::vector& opts, bool isDashDelim); + static ManifestFile::SelectOption GetSelectOpt(const std::string& val, bool canBeNum); + static void RemoveTailAndTrim(std::string& str, const char* tail); + static void BuildDisplayName(Extension::Script& script); + static std::pair, std::string> + ExtractElements(const std::string& str); } namespace V2 @@ -69,10 +67,7 @@ namespace ExtensionLoader bool Load(Extension::Script& script, const char* location, const char* rootDir); } - namespace - { - Extension::Kind GetScriptKind(const std::string& line); - } + static Extension::Kind GetScriptKind(const std::string& line); } #endif diff --git a/daemon/extension/ExtensionManager.cpp b/daemon/extension/ExtensionManager.cpp index 4f0c088db..550ff4def 100644 --- a/daemon/extension/ExtensionManager.cpp +++ b/daemon/extension/ExtensionManager.cpp @@ -29,7 +29,7 @@ namespace ExtensionManager { - const Extensions& Manager::GetExtensions() const + const Extensions& Manager::GetExtensions() const & { std::shared_lock lock{m_mutex}; return m_extensions; @@ -38,20 +38,21 @@ namespace ExtensionManager std::pair Manager::DownloadExtension(const std::string& url, const std::string& extName) { - BString<1024> tmpFileName; - tmpFileName.Format("%s%cextension-%s.tmp.zip", g_Options->GetTempDir(), PATH_SEPARATOR, extName.c_str()); + std::string tmpFileName = std::string(g_Options->GetTempDir()) + + PATH_SEPARATOR + + "extension-" + extName + ".tmp.zip"; std::unique_ptr downloader = std::make_unique(); downloader->SetUrl(url.c_str()); downloader->SetForce(true); downloader->SetRetry(false); - downloader->SetOutputFilename(tmpFileName); + downloader->SetOutputFilename(tmpFileName.c_str()); downloader->SetInfoName(extName.c_str()); WebDownloader::EStatus status = downloader->DownloadWithRedirects(5); downloader.reset(); - return std::make_pair(status, tmpFileName.Str()); + return std::make_pair(status, std::move(tmpFileName)); } boost::optional diff --git a/daemon/extension/ExtensionManager.h b/daemon/extension/ExtensionManager.h index 6a9c63f9a..d1a8e9c8f 100644 --- a/daemon/extension/ExtensionManager.h +++ b/daemon/extension/ExtensionManager.h @@ -60,7 +60,7 @@ namespace ExtensionManager std::pair DownloadExtension(const std::string& url, const std::string& info); - const Extensions& GetExtensions() const; + const Extensions& GetExtensions() const &; private: void LoadExtensionDir(const char* directory, bool isSubDir, const char* rootDir); diff --git a/daemon/extension/ManifestFile.cpp b/daemon/extension/ManifestFile.cpp index bed19e5ef..d96836c12 100644 --- a/daemon/extension/ManifestFile.cpp +++ b/daemon/extension/ManifestFile.cpp @@ -48,185 +48,182 @@ namespace ManifestFile return true; } - namespace + bool ValidateAndSet(const Json::JsonObject& json, Manifest& manifest) { - bool ValidateAndSet(const Json::JsonObject& json, Manifest& manifest) - { - if (!CheckKeyAndSet(json, "author", manifest.author)) - return false; + if (!CheckKeyAndSet(json, "author", manifest.author)) + return false; - if (!CheckKeyAndSet(json, "main", manifest.main)) - return false; + if (!CheckKeyAndSet(json, "main", manifest.main)) + return false; - if (!CheckKeyAndSet(json, "homepage", manifest.homepage)) - return false; + if (!CheckKeyAndSet(json, "homepage", manifest.homepage)) + return false; - if (!CheckKeyAndSet(json, "about", manifest.about)) - return false; + if (!CheckKeyAndSet(json, "about", manifest.about)) + return false; - if (!CheckKeyAndSet(json, "version", manifest.version)) - return false; + if (!CheckKeyAndSet(json, "version", manifest.version)) + return false; - if (!CheckKeyAndSet(json, "name", manifest.name)) - return false; + if (!CheckKeyAndSet(json, "name", manifest.name)) + return false; - if (!CheckKeyAndSet(json, "displayName", manifest.displayName)) - return false; + if (!CheckKeyAndSet(json, "displayName", manifest.displayName)) + return false; - if (!CheckKeyAndSet(json, "kind", manifest.kind)) - return false; + if (!CheckKeyAndSet(json, "kind", manifest.kind)) + return false; - if (!CheckKeyAndSet(json, "license", manifest.license)) - return false; + if (!CheckKeyAndSet(json, "license", manifest.license)) + return false; - if (!CheckKeyAndSet(json, "taskTime", manifest.taskTime)) - return false; + if (!CheckKeyAndSet(json, "taskTime", manifest.taskTime)) + return false; - if (!CheckKeyAndSet(json, "queueEvents", manifest.queueEvents)) - return false; + if (!CheckKeyAndSet(json, "queueEvents", manifest.queueEvents)) + return false; - if (!ValidateOptionsAndSet(json, manifest.options)) - return false; + if (!ValidateOptionsAndSet(json, manifest.options)) + return false; - if (!ValidateCommandsAndSet(json, manifest.commands)) - return false; + if (!ValidateCommandsAndSet(json, manifest.commands)) + return false; + + if (!ValidateTxtAndSet(json, manifest.description, "description")) + return false; - if (!ValidateTxtAndSet(json, manifest.description, "description")) - return false; + if (!ValidateTxtAndSet(json, manifest.requirements, "requirements")) + return false; - if (!ValidateTxtAndSet(json, manifest.requirements, "requirements")) - return false; + return true; + } - return true; - } + bool ValidateCommandsAndSet(const Json::JsonObject& json, std::vector& commands) + { + auto rawCommands = json.if_contains("commands"); + if (!rawCommands || !rawCommands->is_array()) + return false; - bool ValidateCommandsAndSet(const Json::JsonObject& json, std::vector& commands) + for (auto& value : rawCommands->as_array()) { - auto rawCommands = json.if_contains("commands"); - if (!rawCommands || !rawCommands->is_array()) - return false; + Json::JsonObject cmdJson = value.as_object(); + Command command; - for (auto& value : rawCommands->as_array()) - { - Json::JsonObject cmdJson = value.as_object(); - Command command; + if (!CheckKeyAndSet(cmdJson, "name", command.name)) + continue; - if (!CheckKeyAndSet(cmdJson, "name", command.name)) - continue; + if (!CheckKeyAndSet(cmdJson, "displayName", command.displayName)) + continue; - if (!CheckKeyAndSet(cmdJson, "displayName", command.displayName)) - continue; + if (!ValidateTxtAndSet(cmdJson, command.description, "description")) + continue; - if (!ValidateTxtAndSet(cmdJson, command.description, "description")) - continue; + if (!CheckKeyAndSet(cmdJson, "action", command.action)) + continue; - if (!CheckKeyAndSet(cmdJson, "action", command.action)) - continue; + commands.emplace_back(std::move(command)); + } - commands.emplace_back(std::move(command)); - } + commands.shrink_to_fit(); - commands.shrink_to_fit(); + return true; + } - return true; - } + bool ValidateOptionsAndSet(const Json::JsonObject& json, std::vector