Compare commits

...
Author SHA1 Message Date
Kenneth Skovhede 621aada0d1 Reworked the task checker to use polling instead of relying on events 2024-07-19 09:33:20 +02:00
Kenneth Skovhede e5a3fed155 Stringify output 2024-07-19 08:58:48 +02:00
Kenneth Skovhede 67b133a206 Debug restore UI failure 2024-07-19 08:53:09 +02:00
Kenneth Skovhede 5b1df6fa61 Preloading 2024-07-19 08:44:26 +02:00
Kenneth Skovhede f50b49c56e Enable websocket by default 2024-07-18 23:38:33 +02:00
Kenneth Skovhede e05888e557 Testing wait for clickable elements 2024-07-18 23:28:45 +02:00
Kenneth Skovhede c36ec0cbc5 Added support for disabling websocket, and set it to default disabled 2024-07-18 23:17:15 +02:00
Kenneth Skovhede b968dba9ce Guard against multiple guard calls 2024-07-18 23:16:36 +02:00
Kenneth Skovhede 7a85b1763f Better enabling of logging 2024-07-18 22:51:33 +02:00
Kenneth Skovhede 599b4124f2 Test with logs on 2024-07-18 22:44:05 +02:00
Kenneth Skovhede 037e9e179f Merge remote-tracking branch 'origin/master' into feature/remove-httpserver-with-debug 2024-07-18 22:30:09 +02:00
Kenneth Skovhede b9d6084973 Yet-another rework of the reconnect 2024-07-18 22:28:18 +02:00
Kenneth Skovhede c52f08bc6e Added guard against case where the command happens faster than the events can register them 2024-07-18 22:27:39 +02:00
Kenneth Skovhede 85d5b1d74e Fixed error messages for requests with no response 2024-07-18 21:31:16 +02:00
Kenneth Skovhede 63fc93ab38 Updated localization files 2024-07-18 18:18:18 +02:00
Kenneth SkovhedeandGitHub 790f9c06fa Merge pull request #5274 from luixxiul/placeholders
Update placeholders without 'translate'
2024-07-18 18:15:57 +02:00
Suguru Hirahara 12407d4c03 Make placeholders translatable: storj.html and tardigrade.html 2024-07-18 11:28:41 -04:00
Suguru Hirahara 090ecf1af6 Update placeholders without 'translate' 2024-07-18 07:40:50 -04:00
Kenneth Skovhede 105f6e16ff Fixed origin mapping 2024-07-18 10:51:58 +02:00
Kenneth SkovhedeandGitHub 499a3ad575 Merge pull request #5262 from duplicati/feature/update-uplink-fixed-native-binaries
Prepared for new Uplink packages that correctly package the Storj binaries
2024-07-18 10:47:57 +02:00
Kenneth SkovhedeandGitHub f0107b476a Merge pull request #5270 from duplicati/feature/update-localizations
Update localizations
2024-07-18 10:35:37 +02:00
Kenneth Skovhede b7cac4cd51 Removed mixing url with hostnames 2024-07-18 10:34:13 +02:00
Kenneth SkovhedeandGitHub b55ba094b6 Merge pull request #5271 from npodbielski/feature/remove-httpserver
Add websocket support to httpserver
2024-07-18 10:33:04 +02:00
Kenneth Skovhede fecb2bf25a Updated to latest uplink.net packages 2024-07-18 10:08:57 +02:00
Kenneth Skovhede 877b1c811f Updated pot with new strings 2024-07-18 09:57:45 +02:00
Kenneth Skovhede 3bb06311a8 Added localization on additional strings 2024-07-18 09:56:19 +02:00
Kenneth SkovhedeandGitHub 8d96681db6 Merge pull request #5265 from luixxiul/DescriptionS3ClientLong
Fix string `DescriptionS3ClientLong`
2024-07-17 22:18:20 +02:00
Kenneth SkovhedeandGitHub f458355663 Merge pull request #5264 from luixxiul/B2applicationkeyDescription
Replace `B2applicationkeyDescriptionShort` with `B2applicationkeyDescriptionLong`
2024-07-17 22:18:07 +02:00
Kenneth SkovhedeandGitHub e9d7433a72 Merge pull request #5263 from duplicati/feature/report-errors-when-sending-http-report
Added check for valid status code after sending http request with report
2024-07-17 20:48:17 +02:00
Kenneth Skovhede 6195e07808 Updated translation files 2024-07-17 20:32:22 +02:00
Kenneth Skovhede 53059c01dd Pulled from Transifex 2024-07-17 20:26:03 +02:00
Kenneth Skovhede bb274822cc Fixed scripts and config to follow updated TX client 2024-07-17 20:25:35 +02:00
Kenneth Skovhede f74cee2932 Fixed #5267 2024-07-17 19:34:26 +02:00
natan 92f1de07ae Bring back /serverstate endpoint. Fix unauhthorized mdodal when cookie is missing.
Small code cleanup here and there.
2024-07-15 11:07:47 +02:00
Suguru Hirahara f040df8e2f Switch B2applicationkeyDescriptionShort and B2applicationkeyDescriptionLong 2024-07-14 22:38:58 -04:00
Suguru Hirahara ab7e640435 Fix string DescriptionS3ClientLong 2024-07-14 22:36:20 -04:00
natan 27ce549e75 cleanup WebsocketAccessor.cs and StatusService.cs a bit.
Remove /serverstate endpoint
2024-07-12 17:59:21 +02:00
natan 09d30b92e0 Merge remote-tracking branch 'refs/remotes/npodbielski/feature/remove-httpserver' into feature/remove-httpserver 2024-07-12 16:55:59 +02:00
natan bc0a47f768 Merge remote-tracking branch 'origin/feature/remove-httpserver' into feature/remove-httpserver 2024-07-12 16:53:18 +02:00
npodbielskiandGitHub 75bab41034 Merge pull request #1 from duplicati/remove-httpserver-updates-to-reconnect
Changed logic for reconnect to not rely on serverstate API.
2024-07-12 16:53:04 +02:00
Kenneth Skovhede 94d6ab76ee Changed logic for reconnect to not rely on serverstate API.
Changed websocket to send current state on initial connect.
2024-07-11 16:24:22 +02:00
Kenneth Skovhede 1d913e026f Added check for valid status code after sending http request with report 2024-07-10 09:22:07 +02:00
Kenneth Skovhede 974f6bff2f Removed unused file 2024-07-10 09:20:18 +02:00
natan 0ae9990f18 fix 401 in websocket 2024-07-09 15:49:17 +02:00
natan 18ff96c5fe Merge remote-tracking branch 'origin/feature/remove-httpserver' into feature/remove-httpserver 2024-07-09 13:24:13 +02:00
Kenneth Skovhede b39a68bda7 Prepared for new Uplink packages that correctly package the Storj binaries 2024-07-09 12:15:12 +02:00
Kenneth Skovhede 60437d7fc0 Removed duplicate entry in project file 2024-07-09 11:24:17 +02:00
Kenneth SkovhedeandGitHub 618d9015ab Merge pull request #5261 from grzesieklagocki/copyright
Add copyright information to libraries #5258
2024-07-09 11:23:32 +02:00
Grzegorz Łagocki 9b19bac7da Add Copyright Property to *.csproj files 2024-07-09 00:37:18 +02:00
Kenneth Skovhede 6917030417 Treat all auth operation failures as Unauthorized - 401 2024-07-07 10:36:42 +02:00
Kenneth Skovhede 44a45fcd04 Only generate signin token if password is autogenerated 2024-07-07 10:36:11 +02:00
natan f7656f464e fix websocket connection 2024-07-03 22:26:03 +02:00
Kenneth SkovhedeandGitHub 59b00a5a45 Merge pull request #5254 from duplicati/feature/update-mega-library
Updated Mega library to latest
2024-07-03 09:52:51 +02:00
Kenneth Skovhede 31f0cd02ab Updated Mega library to latest 2024-07-02 10:59:18 +02:00
Kenneth Skovhede 627c270025 Merge remote-tracking branch 'origin/master' into feature/remove-httpserver 2024-07-01 22:42:20 +02:00
Kenneth Skovhede 5d0d9fbc80 Simplified initial load fixing for Selenium tests 2024-07-01 22:40:36 +02:00
Kenneth Skovhede 92fea213f9 Removing unsupported custom package files 2024-07-01 22:34:25 +02:00
Kenneth Skovhede 4fe138097b Experiement to detect failed page load 2024-07-01 22:33:54 +02:00
Kenneth Skovhede e25df96d23 Adding cache headers 2024-07-01 22:21:51 +02:00
Kenneth SkovhedeandGitHub 8d82363163 Merge pull request #5251 from duplicati/feature/lower-case-docker-tags
Making docker version tags lowercase
2024-07-01 17:58:31 +02:00
Kenneth Skovhede d7345ad993 Double loading guard 2024-07-01 17:58:16 +02:00
Kenneth Skovhede 85368266ed Added two more loading guards 2024-07-01 14:54:47 +02:00
Kenneth Skovhede 38ac29be13 Making docker version tags lowercase 2024-07-01 14:25:06 +02:00
Kenneth Skovhede 5e9ec4ee98 Fixed selenium tests 2024-07-01 13:36:27 +02:00
Kenneth Skovhede fef9efe4d4 Less agressive push towards the login page on errors 2024-06-30 21:36:06 +02:00
Kenneth Skovhede 2c42108df3 Disable logging to console by default 2024-06-30 21:35:15 +02:00
Kenneth Skovhede f91c4c7328 Removed unused settings 2024-06-30 21:34:54 +02:00
Kenneth Skovhede 54237b1cbb Updated gui test, works locally, not in Docker 2024-06-28 16:03:54 +02:00
Kenneth Skovhede c0f834f511 Removed logspam 2024-06-28 13:22:02 +02:00
Kenneth Skovhede a87984806e Fixed some broken html 2024-06-28 12:49:17 +02:00
Kenneth Skovhede 1c40025666 Fixed missing namespace 2024-06-28 12:21:00 +02:00
Kenneth Skovhede f9170602d3 Re-introduce sudo :'( 2024-06-28 11:58:12 +02:00
Kenneth Skovhede 6cebb6b84f Faster timeout and less sudo 2024-06-28 11:48:07 +02:00
Kenneth Skovhede 8f56220f2f Added support for mandatory login 2024-06-28 11:37:16 +02:00
Kenneth Skovhede be9a3667e6 Fixed a race in refreshing the access token 2024-06-28 11:17:14 +02:00
Kenneth Skovhede c023e29020 Removed proxy support for now 2024-06-28 11:04:12 +02:00
Kenneth Skovhede 8a02dc014e Fixed issue with repair 2024-06-28 10:38:21 +02:00
Kenneth Skovhede 3f51536073 Fixed issue with fetching logs 2024-06-28 10:37:47 +02:00
Kenneth Skovhede d2e91f8db6 Fixed issue with import 2024-06-28 10:37:33 +02:00
Kenneth Skovhede caf7d53583 Fixed auto-login issue 2024-06-28 09:14:08 +02:00
Kenneth Skovhede d3a8ecacad Implemented single operation token.
Fixed export and bugreport download.
2024-06-28 08:56:00 +02:00
Kenneth Skovhede d68d94e7f8 Version bump to v2.0.9.101-2.0.9.101_canary_2024-06-27
You can download this build from:

Binaries: https://updates.duplicati.com/Canary/

Signature file: https://updates.duplicati.com/Canary/2.0.9.101_canary_2024-06-27.signatures.zip
2024-06-27 14:25:55 +02:00
Kenneth Skovhede dab2b23332 Commit before reverting changelog file 2024-06-27 13:42:17 +02:00
Kenneth Skovhede 68ae2a460a Added missing changelog entry 2024-06-27 13:38:25 +02:00
Kenneth Skovhede d261899189 Fixed nonsense commit messages 2024-06-27 13:36:30 +02:00
Kenneth SkovhedeandGitHub 002a47bd1e Merge pull request #5219 from duplicati/feature/update-sharp-aes-crypt
Updated to SharpAESCrypt 2.0
2024-06-27 09:00:25 +02:00
Kenneth SkovhedeandGitHub bb9be1ee4b Merge pull request #5247 from duplicati/feature/recovery-configurable-maxopen-archives
Made the number of open archives configurable
2024-06-27 09:00:07 +02:00
Kenneth SkovhedeandGitHub 17e2266a69 Merge pull request #5231 from duplicati/feature/increase-default-test-coverage
Increase the default test coverage to be 0.1%
2024-06-25 09:58:50 +02:00
Kenneth Skovhede 41b772d385 Documented extra option for recovery tool 2024-06-25 09:54:49 +02:00
Kenneth Skovhede c50e027ecd Made the number of open archives configurable as it can consume some memory. 2024-06-25 09:51:29 +02:00
Kenneth SkovhedeandGitHub a5a03c2a41 Merge pull request #5241 from duplicati/feature/improve-recovery-tool-speed
Improve recovery tool speed
2024-06-25 09:48:58 +02:00
Kenneth SkovhedeandGitHub 991870b9c3 Merge pull request #5234 from duplicati/feature/support-script-arguments
Added support for passing arguments to scripts
2024-06-25 09:48:39 +02:00
Kenneth SkovhedeandGitHub 5de458e74f Merge pull request #5218 from duplicati/feature/upgrade-cocol-1-8
Updated CoCoL library to 1.8
2024-06-25 09:48:02 +02:00
Kenneth SkovhedeandGitHub 8b908cb43d Merge pull request #5246 from duplicati/feature/add-armv7-packages
Added Armv7 deb packages
2024-06-25 09:47:47 +02:00
Kenneth Skovhede 1b3b7fbd1e Removed numbers fro help as they are settings dependent 2024-06-24 19:19:09 +02:00
Kenneth Skovhede b9031e9f20 No need to fix the name, we are only looking for 'token' 2024-06-24 19:17:27 +02:00
Kenneth Skovhede 21fe0f9cfb Fixed a few logic issues, restore flow is now working 2024-06-24 16:00:05 +02:00
Kenneth Skovhede e0d93da2f5 Removed last remaining form input 2024-06-24 15:26:07 +02:00
Kenneth Skovhede b515a6f6f2 Updated to use gzip compression on deb packages 2024-06-24 14:20:28 +02:00
Kenneth Skovhede 6998cc1e28 Added Armv7 deb packages 2024-06-24 12:02:40 +02:00
Kenneth Skovhede 1acda72561 Fixed not creating an empty database 2024-06-24 10:14:03 +02:00
Kenneth Skovhede 246c95c60a Added support for an offset in the recovery tool 2024-06-22 10:27:51 +02:00
Kenneth Skovhede 0855d7fe4d Improved error messages for better client handling options 2024-06-21 16:26:06 +02:00
Kenneth Skovhede 5d7fb66c1c Added some statistics to the output of recovery tool 2024-06-21 15:42:24 +02:00
Kenneth Skovhede 6ab2a63218 Extended recovery tool tests to cover more combinations 2024-06-21 15:15:01 +02:00
Kenneth Skovhede b699937dee Optimized the recovery tool performance. 2024-06-21 15:11:37 +02:00
Kenneth Skovhede d6fe8c1a7d Fixed some naming issues for parameters 2024-06-21 08:00:57 +02:00
Kenneth Skovhede fa7d5e45f7 Fixed auto-reconnect 2024-06-21 07:52:39 +02:00
Kenneth Skovhede 8efab7f746 Fixed an optional parameter 2024-06-21 07:52:28 +02:00
Kenneth Skovhede 3f29331dc6 Fixed a case where listing would fail with empty filters 2024-06-21 07:52:07 +02:00
Kenneth Skovhede 92b82df78b Disabled websocket as it is not complete.
Fallback to longpoll :'(
2024-06-20 22:46:42 +02:00
Kenneth Skovhede fd9b1a1c5b Remove XSRF 2024-06-20 22:43:51 +02:00
Kenneth Skovhede bbff638212 Better support for temporary backups 2024-06-20 22:23:02 +02:00
Kenneth Skovhede c9f8e5786c Minor fixes 2024-06-20 22:22:49 +02:00
Kenneth Skovhede 4392d84da4 Improved startup error detection 2024-06-20 14:27:09 +02:00
Kenneth Skovhede a47af06bb7 Added throttle for request retries on failures 2024-06-20 14:22:49 +02:00
Kenneth Skovhede 34821192fc Fixed hostname filtering 2024-06-20 12:59:24 +02:00
Kenneth Skovhede 3487f2fdf4 Make sure we do not log out users who upgrade 2024-06-20 12:24:14 +02:00
Kenneth Skovhede d3ec5f54fe Missing commit 2024-06-20 12:16:07 +02:00
Kenneth Skovhede 0f1d381c7f Implemented automatic re-login when access token expires 2024-06-20 12:11:54 +02:00
Kenneth Skovhede edc0fb5e4b Fixed re-login for tray-icon 2024-06-20 06:57:46 +02:00
Kenneth Skovhede 25a7667e36 Minor updates to JWT issuance 2024-06-19 22:43:52 +02:00
Kenneth Skovhede d463e6bda7 Removed extra public from interface 2024-06-19 22:38:32 +02:00
Kenneth Skovhede cddf0917e3 Fixed build 2024-06-19 22:37:54 +02:00
Kenneth Skovhede 6945270d49 Setting cookie name depending on port 2024-06-19 14:18:50 +02:00
Kenneth Skovhede 3f29642f6c Implemented JWT tokens.
Added auth requirement on all endpoints.
Added SignIn-, Access- and Refresh-Tokens based on JWT.
Upgraded stored password to be based on PBKDF2.
Added default password assignment.
Updated logic to support auth-header and re-sign-in for tray-icon and web-ui.
2024-06-19 13:54:10 +02:00
Kenneth Skovhede bb73f8f22e Don't pass script as argument to self 2024-06-17 09:54:08 +02:00
Kenneth Skovhede ca4fde938c Revert "Added option to use shell-execute with --run-script-use-document-open"
This reverts commit e32bba1dfc.
2024-06-17 09:47:09 +02:00
Kenneth Skovhede e32bba1dfc Added option to use shell-execute with --run-script-use-document-open 2024-06-17 09:39:17 +02:00
Kenneth Skovhede 1b7e1349ca Adding option for enabling argument parsing in scripts 2024-06-17 09:32:04 +02:00
Kenneth SkovhedeandGitHub 9ca5489ef0 Merge pull request #5235 from IIPoliII/master
Update Poli Systems S3 Provider URL's
2024-06-16 22:20:08 +02:00
PoliandGitHub 9d7fad14cf Update S3Backend.cs - Poli Systems GmbH
Updated the S3 backends of Poli Systems.
S3 became S3-02 and there is a new backend S3-03.
2024-06-15 01:57:45 +02:00
Kenneth Skovhede 828ba240f3 Implemented simpler argument handling based on feedback 2024-06-13 07:40:09 +02:00
Kenneth Skovhede 486e13dd51 Revert "Added support for passing arguments to scripts"
This reverts commit 9b9e8a2adb.
2024-06-13 07:24:17 +02:00
Kenneth Skovhede 37071136b7 Revert "Updated example files to mention the arguments more prominently"
This reverts commit 763048c8bd.
2024-06-13 07:24:07 +02:00
Kenneth Skovhede c0b8129924 Fixed log data 2024-06-13 07:23:30 +02:00
Kenneth Skovhede fe90f8ce3d Consistency update 2024-06-12 22:57:50 +02:00
Kenneth Skovhede 829c434c64 No more appsettings 2024-06-12 22:57:02 +02:00
Kenneth Skovhede 8b8707c811 Moved license to use repo license 2024-06-12 22:56:53 +02:00
Kenneth Skovhede 87c92d40ca Setting commented out conditions, in case we get around to fixing them, 2024-06-12 13:55:15 +02:00
Kenneth Skovhede 763048c8bd Updated example files to mention the arguments more prominently 2024-06-12 11:11:40 +02:00
Kenneth Skovhede 9b9e8a2adb Added support for passing arguments to scripts 2024-06-12 10:54:53 +02:00
Kenneth Skovhede 47ca64ee63 Removed browsertest from sln as it does not currently run on non-windows. 2024-06-11 22:03:07 +02:00
Kenneth Skovhede e88c30edd1 Fixed import/export test 2024-06-11 22:02:45 +02:00
Kenneth Skovhede 4294ee3611 Removed last traces of the custom operating system detection 2024-06-11 21:30:33 +02:00
Kenneth Skovhede 1920b0684d Merge remote-tracking branch 'origin/master' into feature/remove-httpserver 2024-06-11 21:22:29 +02:00
Kenneth SkovhedeandGitHub 973d005c07 Merge pull request #5230 from duplicati/feature/opt-in-local-block-use
Changed logic for local blocks to be opt-in
2024-06-11 10:45:11 +02:00
Kenneth SkovhedeandGitHub f70748359a Merge pull request #5211 from duplicati/feature/remove-alphafs
Removing unsupported AlphaFS.
2024-06-11 10:44:49 +02:00
Kenneth SkovhedeandGitHub 8be2a14f66 Merge pull request #5217 from duplicati/feature/remove-bundled-gpg
Removed bundled GPG binaries for Windows.
2024-06-11 10:43:25 +02:00
Kenneth SkovhedeandGitHub f20d7b9321 Merge pull request #5222 from duplicati/feature/some-s3-option-cleanup
Removed S3 options that have been deprecated for years.
2024-06-11 10:42:32 +02:00
Kenneth SkovhedeandGitHub 1a44be4199 Merge pull request #5221 from duplicati/feature/select-aws-region-endpoint
Update UI to rely on default region hostname for AWS.
2024-06-11 10:41:32 +02:00
Kenneth Skovhede 0e93df8e3e Fixed tests 2024-06-11 07:47:08 +02:00
Kenneth Skovhede bb65e89139 Added missing switch 2024-06-11 06:57:37 +02:00
Kenneth SkovhedeandGitHub e4c578afa2 Merge pull request #5232 from Jojo-1000/fix-compare-exclude
Fix compare on linux showing 0 bytes when exclude filters are used
2024-06-11 06:51:45 +02:00
Kenneth Skovhede d264dbd329 Introducing decimal commandline type 2024-06-11 06:50:25 +02:00
Jojo-1000 e316944a50 Fix compare on linux showing 0 bytes when exclude filters are used.
Closes #5229
2024-06-10 16:00:39 +02:00
Kenneth Skovhede f4dee8a305 Increase the default test coverage to be 0.1% 2024-06-10 11:49:43 +02:00
Kenneth Skovhede f9db217af0 Changed logic for local blocks to be opt-in 2024-06-10 11:37:58 +02:00
Kenneth Skovhede 773f3acfb3 More untangle for FIXMEGlobal 2024-06-09 22:12:03 +02:00
Kenneth Skovhede 270f2f9cea Some work on untangling FIXMEGlobal 2024-06-09 22:00:34 +02:00
Kenneth Skovhede 25bb4f3701 Merge remote-tracking branch 'origin/master' into feature/remove-httpserver 2024-06-09 21:54:02 +02:00
Kenneth SkovhedeandGitHub 9dff0fa953 Merge pull request #5225 from duplicati/feature/license-cleanup
Removed unused Signer.exe program
2024-06-09 21:48:58 +02:00
Kenneth Skovhede 0e12adb210 Fixed usings after merge 2024-06-09 21:33:48 +02:00
Kenneth Skovhede 1d0d7e0152 Fixed library platform usage 2024-06-09 21:24:32 +02:00
Kenneth Skovhede ca425808c5 Merge remote-tracking branch 'origin/master' into feature/remove-httpserver 2024-06-09 21:23:59 +02:00
Kenneth Skovhede 6878a601a9 Fixed XSRF for import/export feature 2024-06-08 13:59:33 +02:00
Kenneth Skovhede 9f79025744 Removed HttpServer.
Re-implemented everything using ASP.NET.
Changed some requests to use JSON instead of FORM data.
Some work towards deleting the FIXMEGlobal instance.
Auth is missing, XSRF does not work correctly.
2024-06-07 15:56:43 +02:00
Kenneth Skovhede 12fb0d36ea Removed unused Signer.exe program
Updated some licenses that snuck in LGPL text from the Kestrel merge.
2024-06-05 11:02:56 +02:00
Kenneth SkovhedeandGitHub bb7b3e5de4 Merge pull request #5220 from duplicati/feature/update-aws-region-list
Added additional AWS S3 regions
2024-06-05 10:55:51 +02:00
Kenneth SkovhedeandGitHub fdc891aa36 Merge pull request #5208 from Jojo-1000/fix-sql-quotes
Fix SQL string quotes
2024-06-04 20:58:20 +02:00
Kenneth Skovhede b11c558ba2 Removed options that have been deprecated for years.
Simplified the parsing of options slightly.
2024-06-04 20:54:57 +02:00
Kenneth Skovhede 2a12fdc493 Update UI to rely on default region hostname for AWS.
This fixes #5214
2024-06-04 20:37:59 +02:00
Kenneth Skovhede c0a49dec2d Removed unused US region, and fixed mapping of location names 2024-06-04 20:13:02 +02:00
Kenneth Skovhede dbdd9a0022 Added additional AWS S3 regions:
- Africa (Cape Town): `af-south-1`
- Asia Pacific (Hyderabad): `ap-south-2`
- Asia Pacific (Jakarta): `ap-southeast-3`
- Asia Pacific (Melbourne): `ap-southeast-4`
- Canada West (Calgary): `ca-west-1`
- Europe (Spain): `eu-south-2`
- Europe (Zurich): `eu-central-2`
- Israel (Tel Aviv): `il-central-1`
- Middle East (UAE): `me-central-1`
- AWS GovCloud (US-East): `us-gov-east-1`
- AWS GovCloud (US-West): `us-gov-west-1`

List of region endpoints is now generated from region table.
2024-06-04 20:00:04 +02:00
Jojo-1000 a5c6c18f26 Prevent SQLite crash on MacOS. 2024-06-04 19:35:06 +02:00
Kenneth SkovhedeandGitHub 516a8e728a Merge pull request #5216 from duplicati/feature/clean-3rdparty-licenses
Updated some licenses
2024-06-04 17:29:00 +02:00
Kenneth Skovhede 95cb6b4e71 Updated to SharpAESCrypt 2.0 2024-06-04 17:27:18 +02:00
Kenneth Skovhede 4b12109e7f Updated CoCoL library to 1.8 2024-06-04 15:33:09 +02:00
Kenneth Skovhede 7dab2f5935 Removed bundled GPG binaries for Windows.
Improved search logic for finding GPG executable on all operating systems.
This also removes the `win-tools` folder.
2024-06-04 15:21:22 +02:00
Kenneth SkovhedeandGitHub 6841ad7fa8 Merge pull request #5215 from duplicati/feature/fix-rendering-issue-angularjs
Fixed an issue rendering non-ascii in AngularJs
2024-06-04 14:07:48 +02:00
Kenneth Skovhede c57321a4f7 Removed Sharp.Xmpp license entries.
Removed duplicate MailKit license.
Added `Artalk.Xmpp` license.
2024-06-04 14:06:15 +02:00
Kenneth SkovhedeandGitHub 245d2f5e95 Merge pull request #5213 from Jojo-1000/xmpp-library-update
Change XMPP library to Artalk.Xmpp
2024-06-04 13:55:56 +02:00
Kenneth SkovhedeandGitHub 9031890456 Merge pull request #5209 from Jojo-1000/platform-support
Fix supported platform warnings (except Captcha)
2024-06-04 11:55:25 +02:00
Kenneth Skovhede 9e0ce5fb0c Fixed an issue rendering non-ascii in AngularJs 2024-06-03 16:17:42 +02:00
Jojo-1000 3ccca04f1c Change XMPP library to Artalk.Xmpp. 2024-06-01 22:44:27 +02:00
Jojo-1000 2b901b511c Change WindowsService to platform-independent target for cross-platform builds. 2024-05-30 21:06:06 +02:00
Kenneth Skovhede 7c9f964eeb Removing unsupported AlphaFS.
This updates #5210
2024-05-30 20:46:25 +02:00
Kenneth Skovhede 5312499107 Fixed issue with incrementing version 2024-05-30 15:38:57 +02:00
Kenneth Skovhede 26b77b29a7 Version bump to v2.0.9.100-2.0.9.100_canary_2024-05-30
You can download this build from:

Binaries: https://updates.duplicati.com/Canary/2.0.9.100_canary_2024-05-30.zip

Signature file: https://updates.duplicati.com/Canary/2.0.9.100_canary_2024-05-30.zip.sig

ASCII signature file: https://updates.duplicati.com/Canary/2.0.9.100_canary_2024-05-30.zip.sig.asc

MD5: 2.0.9.100_canary_2024-05-30.zip.md5

SHA1: 2.0.9.100_canary_2024-05-30.zip.sha1

SHA256: 2.0.9.100_canary_2024-05-30.zip.sha256
2024-05-30 15:35:43 +02:00
Kenneth Skovhede 1fb46d7fd2 Prepare for canary build 2024-05-30 15:34:45 +02:00
Jojo-1000 917e2cd0c4 Remove obsolete custom platform detection. 2024-05-30 02:14:05 +02:00
Jojo-1000 930f1c8bd3 Fix most unsupported platform warnings. 2024-05-30 01:50:02 +02:00
Jojo-1000 1dc1fd83af Add SupportedOSPlatform attribute and target windows where appropriate. 2024-05-30 01:22:16 +02:00
Jojo-1000 2ecfde44f9 Disable double quoted sql string compatibility mode. 2024-05-30 00:00:49 +02:00
Jojo-1000 55284410c7 Fix sql queries that use double quoted strings.
Closes #5202
2024-05-30 00:00:48 +02:00
Kenneth Skovhede 2e7b8fc468 Merge remote-tracking branch 'npodbielski/feature/http-server-modernization' into feature/remove-httpserver 2024-05-28 14:45:26 +02:00
Kenneth SkovhedeandGitHub d9174d1488 Merge pull request #5203 from duplicati/feature/packag-naming-updates
Feature/package naming updates
2024-05-27 13:11:09 +02:00
Kenneth Skovhede 7f2703c5b6 Added option to toggle self-hosted builds 2024-05-27 12:21:19 +02:00
Kenneth SkovhedeandGitHub 2e30a35da9 Merge pull request #5201 from duplicati/feature/fix-direct-restore-blocksize-issue
Implemented test for reproducing issue #5196
2024-05-27 11:14:46 +02:00
Kenneth Skovhede db60e91042 Fixed signature package.
Adde key urls as suggested in #5000
2024-05-27 10:55:06 +02:00
Kenneth Skovhede 3ebc7f7f42 Added support for win-arm64 SQLite 2024-05-26 21:24:21 +02:00
Kenneth Skovhede b13ab5e0cf Support for building win-arm64 2024-05-25 23:36:43 +02:00
Kenneth Skovhede 4b5187561a Better button alignment 2024-05-25 23:24:53 +02:00
Kenneth Skovhede 914316de39 Added missing dialog references 2024-05-25 20:48:23 +02:00
Kenneth Skovhede e0ef501e6a Merged WixUI files into a single extension folder 2024-05-25 20:01:14 +02:00
Kenneth Skovhede 529133d967 Fixed order of buttons.
Fixed running application after install.
2024-05-25 19:39:05 +02:00
Kenneth Skovhede ad4ef7ed95 Implemented the WixUI_FeatureTree with wixl.
Needs a patch for `wixl` to correctly work.
2024-05-25 17:32:26 +02:00
Kenneth Skovhede 58e37e39ef Honor the service flag and do not launch if installed with service intent 2024-05-25 10:34:38 +02:00
Kenneth Skovhede a29b5056ae Implemented slightly better UI for MSI 2024-05-24 14:10:35 +02:00
Kenneth Skovhede 15031af381 Fixed formatting on license.rtf 2024-05-24 14:07:34 +02:00
Kenneth SkovhedeandGitHub d97767689b Merge pull request #5204 from Jojo-1000/fix-stale-permissions
Fix stale action permissions
2024-05-24 11:35:53 +02:00
JanandGitHub fbff3a3ed9 Fix stale action permissions
Action write permissions is required to update the cache (see https://github.com/actions/stale/issues/1133)
2024-05-23 23:29:09 +02:00
Kenneth Skovhede 9ca797944b Remvoved extra license file 2024-05-23 16:37:33 +02:00
Kenneth Skovhede 75bb8942ca Re-introduced the license page in MSI package 2024-05-23 16:25:02 +02:00
Kenneth Skovhede b3f0b1be81 Renamed binaires pre-install for all platforms.
Improved CLI builds, especially for RPM
Fixed permission issues in packages
2024-05-22 13:00:43 +02:00
Kenneth Skovhede 6a1bd40498 Removed BouncyCastle license (project removed 2021) 2024-05-22 11:11:22 +02:00
Kenneth Skovhede 5417099e04 Fixed process name not being set on MacOS 2024-05-22 11:10:43 +02:00
Kenneth Skovhede c890e824ee Implemented test for reproducing issue #5196
Fixed issue by changing order options are written and verified.
Some whitespace changes due to renaming a method
2024-05-21 15:48:29 +02:00
Kenneth SkovhedeandGitHub db79b8e51b Merge pull request #5200 from duplicati/feature/add-missing-executables
Added executables for `SharpAESCrypt` and `Snapshots`
2024-05-21 14:23:45 +02:00
Kenneth SkovhedeandGitHub aaf1067926 Merge pull request #4977 from Jojo-1000/fix-empty-advanced-options
Do not set advanced options with empty string to true
2024-05-21 12:37:43 +02:00
Kenneth Skovhede 9d43685352 Implemented Avalonia debug logger without trace facility 2024-05-21 12:23:02 +02:00
Kenneth Skovhede 95b040d386 Added ConfigurationImporter to the package helper 2024-05-21 12:09:05 +02:00
Kenneth Skovhede afc34e00be Merge remote-tracking branch 'origin/master' into feature/add-missing-executables 2024-05-21 12:08:14 +02:00
Kenneth SkovhedeandGitHub e743cc7b21 Merge pull request #5199 from duplicati/feature/fixes-to-help
Fixed issue with recovery-tool help.
2024-05-21 12:06:36 +02:00
Kenneth Skovhede f3394584af Cleanup for the executable entries 2024-05-21 11:20:40 +02:00
Kenneth Skovhede 095a84dd4b Fixed name for snapshot executable 2024-05-21 11:19:54 +02:00
Kenneth Skovhede 67463adf00 Added configuration importer debug setup 2024-05-21 11:19:34 +02:00
Kenneth Skovhede 2a497acb56 Fixed executable name for configuration import.
Slightly more non-developer friendly error messages
2024-05-21 11:08:41 +02:00
Kenneth Skovhede 8fe14b4754 Fixed namespaces 2024-05-21 10:22:57 +02:00
Kenneth Skovhede 84d7a56ab1 Added executables for SharpAESCrypt and Snapshots 2024-05-21 09:54:01 +02:00
Kenneth Skovhede 05e5fbcf80 Fixed issue with recovery-tool help.
Cleaned up some loading of embedded resourse to rely on type instead of assembly name.
Implemented installed executable name instead of using Windows executable names.
2024-05-21 08:26:40 +02:00
Kenneth SkovhedeandGitHub 9e787c7cce Merge pull request #5195 from duplicati/feature/embed-aliyon-licensedata
Included license data for aliyun-oss with license project
2024-05-21 06:58:41 +02:00
Kenneth SkovhedeandGitHub 54b9063f1b Merge pull request #5198 from Jojo-1000/patch-1 2024-05-19 11:15:52 +02:00
JanandGitHub 3e01a9352c Update stale action and increase operation limit 2024-05-19 10:11:29 +02:00
Kenneth SkovhedeandGitHub a89ccdec7d Merge pull request #5193 from duplicati/feature/avoid-disposing-null
Added null guard for disposing (dispose should not throw)
2024-05-17 14:24:19 +02:00
Kenneth SkovhedeandGitHub e747e8445c Merge pull request #5194 from duplicati/feature/preserve-historic-updater-filelists
Added uploads to store previous versions of the package lists
2024-05-17 14:24:05 +02:00
Kenneth Skovhede 30d68fcf76 Included license data for aliyun-oss with license project 2024-05-17 14:23:52 +02:00
Kenneth Skovhede af75c2e6c9 Added uploads to store previous versions of the package lists during release 2024-05-17 12:19:55 +02:00
Kenneth Skovhede 69a6c09699 Added null guard for disposing (dispose should not throw) 2024-05-17 12:16:55 +02:00
Kenneth SkovhedeandGitHub 91f82a1a1c Merge pull request #5189 from duplicati/feature/micro-fixes-net8
Minor fixes to runtime and packaging
2024-05-16 07:50:43 +02:00
Kenneth SkovhedeandGitHub 6868d1f053 Merge pull request #5191 from Jojo-1000/patch-1
Fix missing auth-username and password in openstack
2024-05-15 17:37:45 +02:00
Kenneth Skovhede 279a0d3ee1 Updated with an init handler that delays all actions posted during init until after the tray icon has initialized 2024-05-15 17:34:49 +02:00
JanandGitHub 55cea2845c Fix missing auth-username and password in openstack.
Closes #5188
2024-05-15 12:09:41 +02:00
Kenneth Skovhede 8c6f4d356d Added more metadata to the latest.json and latest.js files 2024-05-15 11:24:57 +02:00
Kenneth Skovhede 003a70b950 Changed generic update url to match the website 2024-05-15 11:23:14 +02:00
Kenneth SkovhedeandGitHub 058bb26005 Merge pull request #5185 from duplicati/feature/remove-mono-support-in-ssh
Removed support for older Mono builds
2024-05-14 14:42:32 +02:00
Kenneth Skovhede 226f200006 Inject the long-form version name as the version tag 2024-05-14 14:42:15 +02:00
Kenneth Skovhede 238bfdd02c Using Windows identity for reporting username in system info 2024-05-14 14:41:59 +02:00
Kenneth Skovhede 4b15395095 Removed mentions of the managed SSH client. 2024-05-13 22:47:09 +02:00
Kenneth Skovhede 3c3f82ab54 Removed support for older Mono builds 2024-05-13 22:43:23 +02:00
Kenneth SkovhedeandGitHub bda368febf Merge pull request #4975 from Jojo-1000/fix-force-locale
Fix force-locale option for CLI and GUI
2024-05-13 18:28:01 +02:00
Kenneth SkovhedeandGitHub 6a134ce04e Merge pull request #4989 from Jojo-1000/improve-source-file-picker
Improve source file picker
2024-05-13 16:54:27 +02:00
Kenneth SkovhedeandGitHub 67665e47ee Merge pull request #4993 from Jojo-1000/quota-disable
Add option to disable quota and update quota size option
2024-05-13 16:47:48 +02:00
Kenneth SkovhedeandGitHub ca9b48ee98 Merge pull request #4991 from Jojo-1000/fix-recoverytool-empty
Fix recovery tool empty file restore and other bugs
2024-05-13 16:29:48 +02:00
Jojo-1000 e2e8adf02f Merge branch 'master' into fix-force-locale 2024-05-12 00:01:42 +02:00
Jojo-1000 796be8ce29 Merge branch 'master' into improve-source-file-picker 2024-05-11 23:53:57 +02:00
JanandGitHub f79b1f93c4 Merge branch 'master' into fix-recoverytool-empty 2024-05-11 23:49:24 +02:00
Jojo-1000 50808c866b Merge branch 'master' into quota-disable 2024-05-11 23:46:19 +02:00
Kenneth SkovhedeandGitHub 0d6e9487d7 Merge pull request #5182 from duplicati/feature/fix-docker-builds-localization
Added localization support for Docker images
2024-05-08 15:41:58 +02:00
Kenneth Skovhede 7bc34b9ff8 Added missing ca-certificates package to Docker builds 2024-05-08 14:33:09 +02:00
Kenneth SkovhedeandGitHub dac54d4ce5 Merge pull request #5181 from duplicati/feature/fix-decrypt-file-locking
Fixed disposing the read stream before moving the encrypted database.
2024-05-08 13:40:47 +02:00
Kenneth SkovhedeandGitHub c61f8d5b32 Merge pull request #5180 from duplicati/feature/improved-error-handling-for-custom-report-message
Expanded error handling when parsing a custom body for reports.
2024-05-08 13:38:56 +02:00
Kenneth Skovhede 45c7e90479 Added localization support for Docker images 2024-05-08 12:57:40 +02:00
Kenneth Skovhede 83878dcbcd Removed unused pipeline files 2024-05-08 12:52:25 +02:00
Kenneth Skovhede d5f7d69f39 Added missing parenthesis 2024-05-08 12:49:37 +02:00
Kenneth SkovhedeandGitHub e6c347217d Merge pull request #5172 from SimonNyvall/improve-marked-windows-classes
Add SupportedOSPlatform attribute to Windows-specific classes
2024-05-08 12:48:31 +02:00
Kenneth Skovhede 1265f88cf8 Fixed disposing the read stream before moving the encrypted database.
Added more context to the default error message when decryption fails.
2024-05-08 12:48:10 +02:00
Kenneth SkovhedeandGitHub 8968937506 Merge pull request #5179 from duplicati/feature/avalonia-improvement
Removed trace logs from Avaloni by default.
2024-05-08 11:37:22 +02:00
Kenneth Skovhede 792e1abf74 Expanded error handling when parsing a custom body for reports.
This is related to #5170
2024-05-08 11:36:42 +02:00
Kenneth Skovhede a76e692183 Removed trace logs from Avaloni by default.
Addded option to get logs from Avalonia via env variables `DEBUG_AVALONIA=1` or `DEBUG_AVALONIA=2`
Added 1s delay for initializing UI to counter sporadic crashes on startup.
2024-05-07 18:00:45 +02:00
Kenneth SkovhedeandGitHub 33c735c853 Merge pull request #5177 from wjansenw/patch-1
add gnupg to docker
2024-05-06 13:47:47 +02:00
Kenneth SkovhedeandGitHub 288e3534b1 Merge pull request #5176 from duplicati/feature/release-builder-micro-fixes
Micro fixes to release builder logic.
2024-05-06 13:46:40 +02:00
wjansenwandGitHub 81f4e93c09 add gnupg to docker 2024-05-06 13:46:26 +02:00
Kenneth Skovhede 6caa01f051 Micro fixes to release builder logic.
Added example manifest
Fixed not signing pkg files if disabled
2024-05-06 09:43:51 +02:00
Kenneth SkovhedeandGitHub bcd2ec815c Merge pull request #5173 from duplicati/feature/mini-bugfix
Feature/mini bugfix
2024-05-04 09:02:07 +02:00
Kenneth Skovhede f1fb843846 More dynamic handling of files modified during build 2024-05-04 08:13:54 +02:00
Kenneth Skovhede d27a1f1db8 Removed auto-gen file 2024-05-04 08:13:17 +02:00
Kenneth Skovhede b8f9a634e3 Fixed issues with checking signed manifest 2024-05-04 08:01:01 +02:00
Kenneth Skovhede 0e60bf4ca5 Fixed crash in autoupdater help text 2024-05-04 07:34:45 +02:00
Kenneth Skovhede ebd34c853e Safguard against reading older update config 2024-05-04 07:26:54 +02:00
Kenneth Skovhede 43e62f2479 Fixed incorrect and missing image resources 2024-05-04 07:20:31 +02:00
SimonNyvall 7ee8514f7e Add SupportedOSPlatform attribute to Windows-specific classes 2024-05-04 00:31:52 +02:00
Kenneth Skovhede 8458d1efd6 Fixed consolehelper returning wrong content 2024-05-03 15:53:23 +02:00
Kenneth SkovhedeandGitHub 4eedbc118a Merge pull request #5169 from duplicati/feature/add-libicu74
Added `libicu74` to list of icu versions
2024-05-03 11:30:36 +02:00
Kenneth Skovhede f8628d32dc Added libicu74 to list of icu versions 2024-05-03 10:49:15 +02:00
Kenneth SkovhedeandGitHub fe02dfc0de Merge pull request #5163 from duplicati/feature/bundle-storj-binaries
Implemented a workaround for loading Uplink.net binaries
2024-05-03 10:47:20 +02:00
Kenneth SkovhedeandGitHub 2bd921fe25 Merge pull request #5164 from duplicati/feature/revisit-machine-id
Revisiting the machine-id concept.
2024-05-03 10:46:49 +02:00
Kenneth SkovhedeandGitHub 39af4fb521 Merge pull request #5165 from duplicati/feature/updated-handling-of-icons
Reworked tray icons.
2024-05-03 10:46:38 +02:00
Kenneth SkovhedeandGitHub 5646f5ea92 Removed BountySource & AppVeyour. Fixed license badge. 2024-05-03 08:22:48 +02:00
Kenneth SkovhedeandGitHub 9768a7349b Remvoed bountysource and appveyor 2024-05-03 07:48:25 +02:00
Kenneth SkovhedeandGitHub aeb335ce07 Removed open collective signup links 2024-05-03 07:47:42 +02:00
Kenneth Skovhede 67c1213a98 Fixed sending the wrong report message 2024-04-30 10:53:14 +02:00
Kenneth Skovhede c7bde590dc Reworked tray icons.
Added support for light/dark theme.
Updated Avalonia.
Fixed issue with event firing before load.
Changed icons to specific app operating system icons.
New icons for MacOS.
This fixes #5148
2024-04-30 10:28:01 +02:00
Kenneth Skovhede fa73849783 Rename part 2 2024-04-29 21:43:28 +02:00
Kenneth Skovhede cbf98657d3 Rename part 1 2024-04-29 21:43:07 +02:00
Kenneth Skovhede 5b9e294dec Revisiting the machine-id concept.
Removed the text from the update folder as it is no longer being used.
Added a new `machineid.txt` file that controls the machine-id.
De-coupled the machine-id from the installationid as the latter is used for usage reporting, and should not be connected to the machine-id
2024-04-29 17:58:00 +02:00
Kenneth Skovhede 1bdfed6a90 Implemented a workaround for loading Uplink.net binaries 2024-04-29 16:14:09 +02:00
Kenneth SkovhedeandGitHub 8a39372c73 Merge pull request #5152 from duplicati/feature/update-manifest
Implemented the new manifest format
2024-04-29 10:57:09 +02:00
Kenneth SkovhedeandGitHub b51f0ed71e Merge pull request #5155 from duplicati/feature/built-in-sqlite-rc4-decrypt
Added support for decrypting the RC4 encrypted SQLite databases
2024-04-29 10:56:34 +02:00
Kenneth SkovhedeandGitHub b5386573b5 Merge pull request #5158 from duplicati/feature/send-multi-http-reports
Added support for sending reports via HTTP(s) to multiple destinations
2024-04-29 10:54:51 +02:00
Kenneth SkovhedeandGitHub b87ef92e37 Merge pull request #5160 from duplicati/feature/update-ssl-default-to-system-default
Updated TLS version to `None` or `SystemDefault`
2024-04-29 10:54:23 +02:00
Kenneth SkovhedeandGitHub b32c6a4f15 Merge pull request #5161 from duplicati/feature/reduce-dynamic-loader
Reduced dynamic scanning with static linking.
2024-04-29 10:54:09 +02:00
Kenneth SkovhedeandGitHub 7b34dbd022 Merge pull request #5162 from duplicati/feature/add-7z-tests
Added tests for 7z compression
2024-04-29 09:14:29 +02:00
Kenneth Skovhede f708338b2d Added tests for 7z compression 2024-04-29 08:20:24 +02:00
Kenneth Skovhede 508cd56502 Register backend for test 2024-04-27 15:04:18 +02:00
Kenneth Skovhede 2d7e89407c Added option to register custom backends for testing 2024-04-27 14:57:41 +02:00
Kenneth Skovhede 8e25c6e2ab Reduced dynamic scanning with static linking.
Cleaned up some `proj` files.
Added caching to options.
2024-04-26 14:32:41 +02:00
natan a937e8712e fix json naming issue 2024-04-26 09:41:48 +02:00
natan 8625f14744 #1 attempt to fix json naming issue 2024-04-25 17:07:53 +02:00
natan 2773efec93 Selenium Tests - start backup 2024-04-25 17:07:33 +02:00
natan 8fa4875885 fix date handling coming from WS 2024-04-25 17:07:02 +02:00
natan 6e16e1d9ed fix multiple WS messages bug 2024-04-25 17:06:10 +02:00
Kenneth Skovhede dfb6ee0f29 Updated TLS version to None or SystemDefault to use the OS "best match" versions. 2024-04-24 21:17:38 +02:00
natan 097375a6e8 fix LegacyHttpRequestShim.cs not implemented exceptions during backup delete 2024-04-24 16:09:49 +02:00
natan 70741dc99c Merge branch 'refs/heads/master' into feature/http-server-modernization 2024-04-24 15:45:23 +02:00
Kenneth Skovhede db8fb59577 Avoid locking the database file on Windows when looking for an encrypted header 2024-04-24 15:18:45 +02:00
Kenneth SkovhedeandGitHub e927e7230d Merge pull request #5159 from duplicati/feature/update-build-actions-for-ci
Updated dotnet and checkout to use v4
2024-04-24 15:14:52 +02:00
Kenneth SkovhedeandGitHub f80df1b824 Merge pull request #5157 from duplicati/feature/net4-ssl-cleanup
Removed code for supporting .NET < 4.8
2024-04-24 13:32:10 +02:00
Kenneth Skovhede 4657f48a64 Updated dotnet and checkout to use v4 2024-04-24 13:27:14 +02:00
Kenneth SkovhedeandGitHub 8bf183cea1 Merge pull request #5154 from duplicati/feature/move-installer-resources
Some cleanup after introducing the ReleaseBuilder project
2024-04-24 13:22:24 +02:00
Kenneth Skovhede dab3d989e1 Added support for sending reports via HTTP(s) to multiple destinations 2024-04-24 13:16:21 +02:00
Kenneth Skovhede b5f1177bf8 Added typ to the header to align more with JWT 2024-04-24 11:32:40 +02:00
Kenneth Skovhede 60aacaa4bf Merge remote-tracking branch 'origin/master' into feature/move-installer-resources 2024-04-24 11:27:54 +02:00
Kenneth SkovhedeandGitHub 696c431dce Merge pull request #5151 from achims311/master
Minor updates to release
2024-04-24 11:26:10 +02:00
Kenneth Skovhede 787b2bf04f Removed code for supporting .NET < 4.8 2024-04-24 11:21:03 +02:00
Kenneth Skovhede 612f657614 Added nullable to SQLiteLoader.
Avoid checking file if no password is supplied.
2024-04-24 11:16:11 +02:00
Kenneth Skovhede 8961269675 Avoid checking non-existing file 2024-04-24 11:14:35 +02:00
Kenneth SkovhedeandGitHub 76addf3a9e Merge pull request #5153 from duplicati/feature/support-build-only-release-tool
Added option to only build solution (simplifies CI operations)
2024-04-24 09:05:47 +02:00
Kenneth Skovhede 9c0ef09a39 Implemented a built-in decrypt method.
Ported the RC4 algorithm from BouncyCastle.
This fixes #5147
2024-04-23 17:06:32 +02:00
Kenneth Skovhede fe33c4bf93 Fixed some additional paths 2024-04-23 14:28:50 +02:00
Kenneth Skovhede b73e94de7e Removed unused files.
Moved installer files into the ReleaseBuilder
2024-04-23 14:24:38 +02:00
Kenneth Skovhede 6d3e2c7474 Added option to only build solution (simplifies CI operations) 2024-04-23 13:44:22 +02:00
Kenneth Skovhede b6ca526ee7 Implemented the new manifest format
Fixed some issues with the manifest urls.
Changed to records and nullable in some places.
Regenerated the test-keys to use RSA208.
Changed to using built-in JSON for manifest.
This fixes #5145
2024-04-23 13:41:59 +02:00
Achim Schaefer fb45a14e00 minor addition in the command to build the package 2024-04-23 00:26:20 +02:00
Achim Schaefer 37516b7fe6 Additional setting to have idle IO 2024-04-23 00:25:53 +02:00
natan 0fefb316eb Selenium Tests 2024-04-22 10:15:56 +02:00
natan f9f6dfee6b Merge branch 'refs/heads/feature/kestrel-avalonia-upgrade' into feature/http-server-modernization
# Conflicts:
#	Duplicati.Library.RestAPI/UpdatePollThread.cs
#	Duplicati/Server/Program.cs
#	Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js
#	Duplicati/WebserverCore/DuplicatiWebserver.cs
2024-04-22 09:35:53 +02:00
Kenneth SkovhedeandGitHub 0b566ecf1f Merge pull request #5132 from duplicati/feature/1mib-default-blocksize
1 MiB default blocksize
2024-04-21 09:37:02 +02:00
Kenneth SkovhedeandGitHub a31a288819 Merge pull request #5111 from duplicati/feature/upgrade-to-net8
Feature/upgrade to net8
2024-04-21 09:34:10 +02:00
Kenneth SkovhedeandGitHub 75efe35e3d Merge pull request #5112 from duplicati/feature/kestrel-avalonia-upgrade
Kestrel+avalonia upgrade
2024-04-21 09:33:49 +02:00
Kenneth SkovhedeandGitHub 5f422ad605 Merge pull request #5130 from duplicati/feature/change-updater-for-multi-arch
Change updater for multi arch
2024-04-21 09:33:15 +02:00
Kenneth SkovhedeandGitHub a2c4b0a580 Merge pull request #5135 from duplicati/feature/multi-arch-build
Multi arch build
2024-04-21 09:32:38 +02:00
natan 85c2864a9b fix XSRF errors at start 2024-04-19 11:44:12 +02:00
Kenneth Skovhede 2dcafc707b Prepare for experimental release 2024-04-19 09:49:32 +02:00
Kenneth Skovhede 1389bac306 Version bump to v2.0.7.103-2.0.7.103_canary_2024-04-19
You can download this build from:

Binaries: https://updates.duplicati.com/canary/duplicati-2.0.7.103_canary_2024-04-19.zip

Signature file: https://updates.duplicati.com/canary/duplicati-2.0.7.103_canary_2024-04-19.zip.sig

ASCII signature file: https://updates.duplicati.com/canary/duplicati-2.0.7.103_canary_2024-04-19.zip.sig.asc

MD5: 2933f0e8508db5708ea4c5ce62243a33

SHA1: aa8914db593d944748cfe03b0692ac5ccbd200d3

SHA256: 3305708527a7bce7228adcaf642a7c3b525479ea7a4674bc4dd833fe40996cb8
2024-04-19 08:36:32 +02:00
Kenneth Skovhede c4eab9ce82 Fixed infinite loop in test 2024-04-18 18:21:10 +02:00
Kenneth Skovhede 59079675e9 Switch selenium to chrome 2024-04-18 16:21:49 +02:00
Kenneth Skovhede 502de4933f Ported selenium fixes from main branch 2024-04-18 16:07:57 +02:00
Kenneth Skovhede 5e62a33f2e Restored options to support different selenium configurations 2024-04-18 16:05:11 +02:00
Kenneth Skovhede 220c550181 Run as root in selenium container 2024-04-18 15:37:11 +02:00
Kenneth Skovhede bb99a4a6b1 Made the unittest download more robust 2024-04-18 15:34:34 +02:00
Kenneth Skovhede 9d1f985be6 Updated selenium runner env 2024-04-18 15:09:48 +02:00
Kenneth Skovhede 9809ef5a78 Updated test workflow 2024-04-18 14:32:17 +02:00
Kenneth Skovhede c2a37d0cd8 Merge remote-tracking branch 'origin/master' into feature/multi-arch-build 2024-04-18 14:09:53 +02:00
Kenneth Skovhede 62f707be6d Fixed including the machineId in reports 2024-04-18 14:07:05 +02:00
Kenneth Skovhede 22043c8d12 Fixed install on-beta MSI removing files 2024-04-18 13:52:54 +02:00
Kenneth Skovhede bde36461e5 Fixed MSI icons 2024-04-18 13:38:28 +02:00
natan 23a9c72115 Selenium Tests 2024-04-18 12:43:56 +02:00
Kenneth Skovhede fcc95fa936 Fixed flaky test 2024-04-18 11:49:39 +02:00
natan c45c1b3961 Merge branch 'refs/heads/feature/kestrel-avalonia-upgrade' into feature/http-server-modernization 2024-04-17 21:19:10 +02:00
Kenneth Skovhede 1a9fa8f52a Cleaned some extra WIX files.
Added version numbers to MSI build.
2024-04-17 16:14:55 +02:00
Kenneth Skovhede 7b9af8d237 Fixed an issue with MacOS packages not being correctly placed during build 2024-04-16 15:26:25 +02:00
Kenneth Skovhede b3f3fcff70 Added documentation for ReleaseBuilder 2024-04-16 15:05:59 +02:00
Kenneth Skovhede 6362dd3cf8 Updated query to remove warning from SQLite logging 2024-04-16 14:19:15 +02:00
Kenneth Skovhede 09b5be5e64 Reverted AlphaFS and AlphaVSS to use the .NetCore35 libraries directly 2024-04-16 14:18:18 +02:00
Kenneth Skovhede cc5d73d1c6 Disabled bundled binary components for Storj 2024-04-16 07:50:27 +02:00
Kenneth Skovhede 1f6e1d238d Fixed MSI program files on x64.
Remove unused installer things.
2024-04-16 07:22:54 +02:00
Kenneth Skovhede 675d361e62 Removed deprecated Tardigrade backend 2024-04-15 22:20:54 +02:00
Kenneth Skovhede 142e8e79f2 Fixed a 30s systeminfo delay 2024-04-15 22:17:09 +02:00
Kenneth Skovhede 6994c301b4 Removed untracked file 2024-04-15 13:37:33 +02:00
Kenneth Skovhede e871bea8aa Fixed typo 2024-04-15 13:33:28 +02:00
Kenneth Skovhede d8159f6772 More disable flags for debug runs 2024-04-15 13:24:08 +02:00
Kenneth Skovhede b84f235ffc Updated SQLite M3 binaries to fix crashes 2024-04-15 13:22:39 +02:00
Kenneth Skovhede 3e3f1cacfa Added VSCode debug targets 2024-04-15 13:22:22 +02:00
Kenneth Skovhede a0c0cbf3d5 Removed mentions of Mono in code, and fixed some entry paths pointing to the dll instead of the exe 2024-04-15 13:20:39 +02:00
Kenneth Skovhede 49fb45859c Fixed some incorrectly quoted literals in SQL statements 2024-04-15 08:24:01 +02:00
Kenneth Skovhede f8cec10a6d Added libssl for docker images 2024-04-15 07:59:28 +02:00
Kenneth Skovhede bf7aff469d Disable loading Kestrel until the API is ready 2024-04-12 15:32:25 +02:00
Kenneth Skovhede a70775ed30 Hacky support for libicu package versioning on Debian 2024-04-11 19:35:25 +02:00
Kenneth Skovhede 7c130cc00f Improved cleanup after building 2024-04-11 13:43:09 +02:00
Kenneth Skovhede d4c695f28b Added support files for packages list in json+js 2024-04-11 13:40:58 +02:00
Kenneth Skovhede 4a89f9bb52 Added sign key to signature file 2024-04-11 13:06:58 +02:00
Kenneth Skovhede 55b22ee18b Added support for uploading packges in the build flow.
Improved re-run of failed builds.
2024-04-11 12:44:12 +02:00
Kenneth Skovhede 4dd16d6ae3 Added binary files for Storj 2024-04-09 16:41:14 +02:00
Kenneth Skovhede 162c9291e7 Removed unused redirect file 2024-04-09 16:40:57 +02:00
Kenneth Skovhede b871ab5058 Updated debug build setup 2024-04-09 15:26:52 +02:00
Kenneth Skovhede 53e585b594 Unified names for Docker builds 2024-04-09 15:23:58 +02:00
Kenneth Skovhede af64822346 Fixed password reading issue 2024-04-09 15:23:37 +02:00
Kenneth Skovhede 9610a52f9d Updated list of supported targets 2024-04-09 15:23:18 +02:00
Kenneth Skovhede b6e1f7b75f Reverted keys to 128 bytes (1024 bit keys) as the current sign key is 1024 bits.
Regnerated 1024bit dummy keys for testing.
2024-04-09 15:06:34 +02:00
Kenneth Skovhede f6678586e0 Fixed docker builds to use arch-specific tini.
Not using Alpine baseimage as it needs special dotnet builds.
2024-04-09 15:04:48 +02:00
Kenneth Skovhede c988ccdf76 Fixed RPM package builds.
Updated DEB packages to use relative symlinks
2024-04-09 13:02:13 +02:00
Kenneth Skovhede 516ae7d59b Moved shared linux installer files into common folder 2024-04-09 10:23:07 +02:00
Kenneth Skovhede 7180b1af82 Installing services in deb-files.
Added support for debian+ubuntu
2024-04-08 23:26:35 +02:00
Kenneth Skovhede 6cd9eb0f0c Fixed missing executables.
Removed debug config folder in packages.
Use systematic names for packages
2024-04-08 14:29:09 +02:00
Kenneth Skovhede 35121a9b02 Added mising packages fro deb installer 2024-04-08 13:36:31 +02:00
Kenneth Skovhede d8d83f2f11 Fixed debian symlinks 2024-04-08 13:36:12 +02:00
Kenneth Skovhede 3b831695a3 Fixed macos launcing renamed executables 2024-04-08 13:35:55 +02:00
Kenneth Skovhede 037ce702fe Use custome builds of SQLite for non-supported platforms 2024-04-08 13:34:33 +02:00
Kenneth Skovhede f0d61c0f1a Prevent crash on failure shutdown 2024-04-08 07:47:12 +02:00
Kenneth Skovhede b5e9ce18cd Updated old non-https urls 2024-04-06 11:01:08 +02:00
Kenneth Skovhede 52dccc74d7 Updated support for executables in Linux zip archives.
Prefixed package names with `duplicati-`
2024-04-06 10:59:59 +02:00
Kenneth Skovhede 13367f4ab4 Added POSIX execute bits for zip packages 2024-04-06 10:41:43 +02:00
Kenneth Skovhede 847be2d00a More fixes to support transistions to new updater 2024-04-06 10:27:33 +02:00
Kenneth Skovhede 149703d0c8 Report package id in system info 2024-04-05 16:50:53 +02:00
Kenneth Skovhede d15ed599d9 Prevent crashes on debug builds 2024-04-05 16:50:21 +02:00
Kenneth Skovhede b89861721b Fixed MacOS signing of pkg files 2024-04-05 16:46:09 +02:00
Kenneth Skovhede 8f5025af62 Fixed code signing on MacOS 2024-04-05 15:26:39 +02:00
Kenneth Skovhede ff560c6fef Simplified the reading of MacOS config file 2024-04-05 15:25:08 +02:00
Kenneth Skovhede b2bea69f6e Added support for loading licenses from outside the binary folder on MacOS 2024-04-05 15:24:48 +02:00
Kenneth Skovhede d318467b09 Removed Spatial library 2024-04-05 15:24:27 +02:00
Kenneth Skovhede 3731622722 Fixed deb package format 2024-04-04 18:25:16 +02:00
Kenneth Skovhede 79409a8359 Added support for building debug and with custom version 2024-04-04 16:08:45 +02:00
Kenneth Skovhede 605deefebd Added support for creating the GPG signatures for all files 2024-04-04 15:53:11 +02:00
Kenneth Skovhede 02d476d16c Added support for writing data to stdin 2024-04-04 15:44:28 +02:00
Kenneth Skovhede 23065d44ef Version bump to v2.0.7.102-2.0.7.102_canary_2024-04-03
You can download this build from:

Binaries: https://updates.duplicati.com/canary/duplicati-2.0.7.102_canary_2024-04-03.zip

Signature file: https://updates.duplicati.com/canary/duplicati-2.0.7.102_canary_2024-04-03.zip.sig

ASCII signature file: https://updates.duplicati.com/canary/duplicati-2.0.7.102_canary_2024-04-03.zip.sig.asc

MD5: c08ebf88cc6b4c164b6dcb3da5a2af94

SHA1: c593036adda4b2599023e88398c9aa59f57cb91b

SHA256: 46df0472bce7e63554808dd6924b957eb2cd4d7c08b76129d590c2d3c9aa40c2
2024-04-03 11:24:57 +02:00
Kenneth SkovhedeandGitHub 45c3d6828a Merge pull request #5141 from duplicati/feature/improved-reporting-on-exception
Changed logic for reporting exceptions
2024-04-03 11:04:24 +02:00
natan d78b9f2c63 WIP 2024-04-03 10:40:29 +02:00
Kenneth Skovhede 9f0810612a Changed logic for reporting exceptions, so all statistics are reported despite an exception stopping the backup 2024-04-02 22:31:55 +02:00
Kenneth Skovhede f1e767b9cc Work on creating the signed manifests 2024-03-27 19:52:40 +01:00
Kenneth Skovhede cc091f06fe Minor fix to increase compatibility with older clients 2024-03-27 11:25:16 +01:00
Kenneth Skovhede a1a4042198 Added support for having multiple valid keys for a manifest 2024-03-27 11:24:49 +01:00
natan 6041c8f1d9 Merge remote-tracking branch 'npodbielski/feature/http-server-modernization' into feature/http-server-modernization
# Conflicts:
#	Duplicati/WebserverCore/DuplicatiWebserver.cs
#	Duplicati/WebserverCore/Extensions/ServiceCollectionsExtensions.cs
#	Duplicati/WebserverCore/Middlewares/StaticFilesMiddleware.cs
#	Duplicati/WebserverCore/appsettings.Development.json
#	Duplicati/WebserverCore/appsettings.json
2024-03-26 18:33:13 +01:00
natan 5d53eddb32 WIP 2024-03-26 18:32:56 +01:00
Kenneth Skovhede e97783382d Added support for RPM builds 2024-03-26 11:56:07 +01:00
Kenneth Skovhede 760eea01c8 Removed leftovers for Docker 2024-03-25 11:54:33 +01:00
Kenneth Skovhede 4e837a865c Added support for Docker images.
Added more commandline options.
Added the package id to builds.
2024-03-25 11:53:52 +01:00
natan 32e852a392 WIP 2024-03-24 17:54:21 +01:00
Kenneth Skovhede 544dc93dff Added support for building deb files.
Reworked the way symlinks are used, as zip files have no symlink support.
2024-03-24 17:34:20 +01:00
Kenneth Skovhede 3fa6977b1f Updated to handle more than 7 options in the command 2024-03-22 15:20:45 +01:00
Kenneth Skovhede 3c65db405a Refactor build code into steps 2024-03-22 14:24:16 +01:00
Kenneth Skovhede b4aad97697 Fixed pkg build issues 2024-03-22 12:27:13 +01:00
Kenneth Skovhede 9c4dcb275c Removed debug code 2024-03-22 12:16:55 +01:00
Kenneth Skovhede 0b0a4491de Dangling changes 2024-03-22 12:16:19 +01:00
Kenneth Skovhede dbfd564a03 Added support for building MSI, DMG and PKG files 2024-03-22 12:15:53 +01:00
Kenneth Skovhede 3da45c53df Initial work on building package folders.
Next step is building the installers.
2024-03-20 16:17:17 +01:00
Kenneth Skovhede 7dfa19d48b Merge branch 'master' into feature/1mib-default-blocksize 2024-03-18 15:19:42 +01:00
Kenneth Skovhede f77f77ad3a Fixed types to allow building release executables 2024-03-15 15:20:28 +01:00
Kenneth Skovhede 76983002e6 Fixed a release build issue after removing autoupdater 2024-03-15 15:06:09 +01:00
Kenneth Skovhede 240dfc1784 Merge branch 'feature/kestrel-avalonia-upgrade' into feature/change-updater-for-multi-arch 2024-03-15 14:47:32 +01:00
Kenneth Skovhede 8a7a69cd50 Merge remote-tracking branch 'origin/master' into feature/kestrel-avalonia-upgrade 2024-03-15 14:30:02 +01:00
Kenneth Skovhede 7eff0dd2af Merge remote-tracking branch 'origin/master' into feature/change-updater-for-multi-arch 2024-03-15 14:23:12 +01:00
Kenneth Skovhede 115e887802 Implemented new updater logic that supports multi-arch distributions. 2024-03-15 14:18:56 +01:00
Kenneth Skovhede 34b2b02025 Fixed stray letter 2024-03-15 13:44:27 +01:00
Kenneth Skovhede b8151b1ddf Merge remote-tracking branch 'origin/master' into feature/kestrel-avalonia-upgrade 2024-03-11 09:52:27 +01:00
Kenneth Skovhede a8ee4f2ba1 Post merge build fixes 2024-03-08 11:44:38 +01:00
Kenneth Skovhede b27323c705 Merge remote-tracking branch 'origin/master' into feature/kestrel-avalonia-upgrade 2024-03-08 11:40:33 +01:00
Kenneth Skovhede c49e5609a9 Merge remote-tracking branch 'origin/master' into feature/kestrel-avalonia-upgrade 2024-03-07 06:35:15 +01:00
Kenneth Skovhede cbe8c43414 Minor updates to tray icon 2024-03-06 22:18:03 +01:00
Kenneth Skovhede 29b9afa6b3 Added VS Code helpers 2024-03-06 15:09:40 +01:00
Kenneth Skovhede bbbf77427e Fixed build 2024-03-06 15:09:31 +01:00
Kenneth Skovhede 989aa925a0 Fixes to Avalonia runner.
Added cross-thread calling support.
2024-03-06 12:37:07 +01:00
Kenneth Skovhede 51f93301fd Updated the build to use the SQLite provided packages with native binaries 2024-03-05 08:55:46 +01:00
Kenneth Skovhede 9377fdffc1 Unified the way the version is extracted from the SQLite library 2024-03-05 08:55:13 +01:00
Kenneth Skovhede a4fd6e9c8c Removed stray include 2024-03-04 14:43:56 +01:00
Kenneth Skovhede 7cc3d4e662 Removed includes from upgrader tool 2024-03-04 14:39:07 +01:00
Kenneth Skovhede 52265395c5 Using only Avalonia for TrayIcon 2024-03-04 14:34:38 +01:00
Kenneth Skovhede 2303f9151f Cleanup after merge 2024-03-04 14:00:55 +01:00
Kenneth Skovhede 473c6cbbb8 Merge commit '4f577c65a4d8806f79637c50c21ca3a683c5a07a' into feature/kestrel-avalonia-upgrade 2024-03-04 12:21:53 +01:00
Kenneth Skovhede 281ff48189 Fixed build of the server 2024-03-03 15:42:48 +01:00
Kenneth Skovhede 8e1347c52c Disable MacOS support for trayicon as it will be replaced 2024-03-03 15:42:32 +01:00
Kenneth Skovhede d7f027b9e2 Fixed usings in unit tests 2024-03-03 15:41:49 +01:00
Kenneth Skovhede 2ce049cecb Fixes to the installer and WindowsService 2024-03-03 15:24:49 +01:00
Kenneth Skovhede 17c2ab9dc6 Fixes to license file resources 2024-03-03 15:24:23 +01:00
Thomas Suckow 4f577c65a4 Fix backward logic to try to fix mac build 2024-03-01 22:27:03 -08:00
Thomas Suckow bc5f17ebf1 Try fix mac build 2024-03-01 21:57:36 -08:00
Kenneth Skovhede 3501cdee08 Added sharepoint from #3124 2024-03-01 14:45:31 +01:00
Kenneth Skovhede 6feb7c0200 Smaller fixes to build 2024-03-01 14:30:28 +01:00
Kenneth Skovhede f395da68d7 Hacky support for 7z 2024-03-01 14:30:28 +01:00
Kenneth Skovhede d3d4fc1434 More cleanup after using Mono.Posix 2024-03-01 14:30:28 +01:00
Kenneth Skovhede c08571efba Updating S3 to use the async interface 2024-03-01 14:30:28 +01:00
Kenneth Skovhede 5c1d6bda76 Fixes for OAuth 2024-03-01 14:30:28 +01:00
Kenneth Skovhede cfbfdad2ab Fixes for Azure Blob 2024-03-01 14:30:28 +01:00
Kenneth Skovhede fb863ea14e Updated the common library, using the Nuget Posix package 2024-03-01 14:30:28 +01:00
Kenneth Skovhede 97d89bb46f Disable app-domains 2024-03-01 14:30:28 +01:00
Kenneth Skovhede c168849dff Hand-picked changes from #3124 2024-03-01 14:30:28 +01:00
Kenneth Skovhede aa20088c39 Tool based upgrade of all projects with some manual update 2024-03-01 14:29:54 +01:00
Kenneth Skovhede 35cc847df7 Merge branch 'master' into feature/upgrade-to-sdk-style-projects 2024-03-01 14:28:55 +01:00
Thomas Suckow 65e907d79f Fix release build dependancy problem 2024-02-29 22:06:45 -08:00
Thomas Suckow a3bbf63561 Merge remote-tracking branch 'origin/feature/upgrade-to-sdk-style-projects' into feature/net5-kestrel
# Conflicts:
#	.appveyor.yml
#	.github/workflows/tests.yml
#	BuildTools/AutoUpdateBuilder/AutoUpdateBuilder.csproj
#	BuildTools/DependencyFinder/DependencyFinder.csproj
#	BuildTools/GnupgSigningTool/GnupgSigningTool.csproj
#	BuildTools/UpdateVersionStamp/UpdateVersionStamp.csproj
#	Duplicati CommandLine Only.sln
#	Duplicati.Library.RestAPI/RESTMethods/RequestInfo.cs
#	Duplicati.Library.RestAPI/Runner.cs
#	Duplicati.sln
#	Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
#	Duplicati/CommandLine/BackendTester/app.config
#	Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
#	Duplicati/CommandLine/BackendTool/app.config
#	Duplicati/CommandLine/ConfigurationImporter/Duplicati.CommandLine.ConfigurationImporter.csproj
#	Duplicati/CommandLine/Duplicati.CommandLine.csproj
#	Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
#	Duplicati/CommandLine/app.config
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/Assets/icons/normal-warning.png
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/app.config
#	Duplicati/Library/AutoUpdater/Duplicati.Library.AutoUpdater.csproj
#	Duplicati/Library/Backend/AlternativeFTP/Duplicati.Library.Backend.AlternativeFTP.csproj
#	Duplicati/Library/Backend/AzureBlob/Duplicati.Library.Backend.AzureBlob.csproj
#	Duplicati/Library/Backend/Backblaze/Duplicati.Library.Backend.Backblaze.csproj
#	Duplicati/Library/Backend/Box/Duplicati.Library.Backend.Box.csproj
#	Duplicati/Library/Backend/CloudFiles/Duplicati.Library.Backend.CloudFiles.csproj
#	Duplicati/Library/Backend/Dropbox/Duplicati.Library.Backend.Dropbox.csproj
#	Duplicati/Library/Backend/FTP/Duplicati.Library.Backend.FTP.csproj
#	Duplicati/Library/Backend/File/Duplicati.Library.Backend.File.csproj
#	Duplicati/Library/Backend/GoogleServices/Duplicati.Library.Backend.GoogleServices.csproj
#	Duplicati/Library/Backend/HubiC/Duplicati.Library.Backend.HubiC.csproj
#	Duplicati/Library/Backend/Idrivee2/Duplicati.Library.Backend.Idrivee2.csproj
#	Duplicati/Library/Backend/Jottacloud/Duplicati.Library.Backend.Jottacloud.csproj
#	Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj
#	Duplicati/Library/Backend/OAuthHelper/Duplicati.Library.OAuthHelper.csproj
#	Duplicati/Library/Backend/OneDrive/Duplicati.Library.Backend.OneDrive.csproj
#	Duplicati/Library/Backend/OpenStack/Duplicati.Library.Backend.OpenStack.csproj
#	Duplicati/Library/Backend/Rclone/Duplicati.Library.Backend.Rclone.csproj
#	Duplicati/Library/Backend/S3/Duplicati.Library.Backend.S3.csproj
#	Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj
#	Duplicati/Library/Backend/SharePoint/Duplicati.Library.Backend.SharePoint.csproj
#	Duplicati/Library/Backend/Sia/Duplicati.Library.Backend.Sia.csproj
#	Duplicati/Library/Backend/Storj/Duplicati.Library.Backend.Storj.csproj
#	Duplicati/Library/Backend/TahoeLAFS/Duplicati.Library.Backend.TahoeLAFS.csproj
#	Duplicati/Library/Backend/Tardigrade/Duplicati.Library.Backend.Tardigrade.csproj
#	Duplicati/Library/Backend/TencentCOS/Duplicati.Library.Backend.TencentCOS.csproj
#	Duplicati/Library/Backend/WEBDAV/Duplicati.Library.Backend.WEBDAV.csproj
#	Duplicati/Library/Common/Duplicati.Library.Common.csproj
#	Duplicati/Library/Compression/Duplicati.Library.Compression.csproj
#	Duplicati/Library/DynamicLoader/Duplicati.Library.DynamicLoader.csproj
#	Duplicati/Library/Encryption/Duplicati.Library.Encryption.csproj
#	Duplicati/Library/Interface/Duplicati.Library.Interface.csproj
#	Duplicati/Library/Localization/Duplicati.Library.Localization.csproj
#	Duplicati/Library/Logging/Duplicati.Library.Logging.csproj
#	Duplicati/Library/Main/Duplicati.Library.Main.csproj
#	Duplicati/Library/Modules/Builtin/CheckMonoSSL.cs
#	Duplicati/Library/Modules/Builtin/Duplicati.Library.Modules.Builtin.csproj
#	Duplicati/Library/Modules/Builtin/SendJabberMessage.cs
#	Duplicati/Library/SQLiteHelper/Duplicati.Library.SQLiteHelper.csproj
#	Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj
#	Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj
#	Duplicati/Library/Utility/Duplicati.Library.Utility.csproj
#	Duplicati/Library/Utility/HashAlgorithmHelper.cs
#	Duplicati/Library/Utility/Power/WindowsPowerSupplyState.cs
#	Duplicati/License/Duplicati.License.csproj
#	Duplicati/Server/Duplicati.Server.Serialization/Duplicati.Server.Serialization.csproj
#	Duplicati/Server/Duplicati.Server.csproj
#	Duplicati/Server/app.config
#	Duplicati/Service/Duplicati.Service.csproj
#	Duplicati/Service/app.config
#	Duplicati/Tools/Duplicati.Tools.csproj
#	Duplicati/UnitTest/Duplicati.UnitTest.csproj
#	Duplicati/UnitTest/GeneralBlackBoxTesting.cs
#	Duplicati/UnitTest/app.config
#	Duplicati/WindowsService/WindowsService.csproj
#	Installer/debian/docker/debian/control
#	Tools/SQLiteTool/SQLiteTool.csproj
#	Tools/ZipFileDebugger/ZipFileDebugger.csproj
#	guiTests/guiTest.py
#	thirdparty/UnixSupport/UnixSupport.csproj
#	thirdparty/alphavss/Homepage.txt
#	thirdparty/alphavss/License.txt
#	thirdparty/alphavss/licensedata.json
2024-02-29 21:55:17 -08:00
Kenneth Skovhede 72e47e419c Fixed referencing Windows.Forms via reflection for cross-platform build 2024-02-26 14:50:43 +01:00
Kenneth Skovhede 133dda94a3 Fixed complicated build with Xamarin Mac 2024-02-26 14:50:18 +01:00
Kenneth Skovhede 83a6e262c4 Updated release process to handle SDK style project files 2024-02-26 14:49:59 +01:00
Kenneth Skovhede 3bf6b162ca Upgraded utility projects.
Removed redundant packages files.
Removed `mozroots` in prepare of switch to non-mono releases.
2024-02-26 08:24:48 +01:00
Kenneth Skovhede 22acb8bdda Fixed compile issues after upgrade 2024-02-26 06:59:30 +01:00
Kenneth Skovhede d7b6dd90be Updated all projects to use SDK-style projects using upgrade-assist 2024-02-25 16:19:25 +01:00
Jojo-1000 a1349b1af9 Show filter group rules in source file picker.
Add REST handler /systeminfo/filtergroups that returns the filter strings for all filter groups on the system.
Use these filter strings to apply filter groups to the source file picker.
2024-01-16 18:52:31 +01:00
Jojo-1000 74db90924e Fix processing files repeatedly if present in multiple sources.
This can happen if a source is added to force including a system folder.
2024-01-16 18:52:30 +01:00
Jojo-1000 5acf4dbaad Improve file in-/excluding logic in source file picker.
Add filters to the beginning instead of the end of the list, so they are not overridden by more general ones.
If a file is excluded, add an include filter to include the file.
2024-01-16 18:52:30 +01:00
Jojo-1000 9dbdbb1b2f Show files excluded via 'Exclude' section in source picker.
Add more metadata to the file list returned by server, so that the source file picker can display filters based on file attributes.
Correctly display 'X' in file list if a file is excluded by attributes and not included as a source (#4751).
Fix directory separator issue when loading the page and prevent opening folders in source file list.
2024-01-16 18:52:30 +01:00
Jojo-1000 c9e9b0eeb7 Scroll to source data path on double click. 2024-01-16 18:52:30 +01:00
Jojo-1000 aa365f7f34 Update --quota-size option to assign a backup size.
The assigned quota size is checked in addition to the reported backend quota (if available). It can be used to limit the backup size on the remote. Warnings are created according to the same quota warning threshold.
Previously, this option had no function.
2023-07-16 19:49:54 +02:00
Jojo-1000 0754a5cd72 Ignore File backend quota if total size is zero.
Mono sometimes reports the total size of unknown file systems as zero. Because it should be obvious when the size is actually zero, ignore the quota in this case.
2023-07-16 19:24:37 +02:00
Jojo-1000 8af1dbb6fd Add --quota-disable option to disable reported backend quota.
If set, the backend is treated as if it does not report a quota at all. No warnings and errors are created and no quota values are set in the backup log.
This option is intended to be used if a backend reports a wrong quota, so it needs to be disabled.
2023-07-16 19:16:11 +02:00
Jojo-1000 cff1049347 Add unit tests for recovery tool restore paths.
Test that paths are generated correctly from a different source OS.
Also test that empty files are restored by recovery tool.
2023-07-11 22:48:28 +02:00
Jojo-1000 6b5623651c Fix recovery tool restore paths on different OS.
On Linux, paths were created with \ instead of / separators if backup was originally from Windows (#4884).
Also fix bug that created one unnecessary level of directories in the restore path.
2023-07-11 22:37:08 +02:00
Jojo-1000 0f5b4b9707 Fix restore of empty files with recovery tool.
Empty files do not have data blocks stored, so don't try to get a block for empty files.
2023-07-10 16:44:24 +02:00
Jojo-1000 b9d4be60ca Do not set advanced options with empty string to true.
There are advanced options such as force-local that expect an empty string in some cases. While saving, these were replaced with 'true' even though there was an equals sign.
Now only options without an equals sign are set to true.

Closes #4757
2023-06-23 16:38:54 +02:00
Jojo-1000 b6643fa473 Add documentation comments for LocaleChange. 2023-06-23 14:22:36 +02:00
Jojo-1000 708715e705 Fix force-locale option for CLI and GUI.
- Localization culture is set from multiple threads on the server, so use current local context for every new call instead of global context
- Change locale before executing help commands if flag is present
- When force-locale is set, also change locale for log messages

Closes #4176
2023-06-23 13:30:46 +02:00
Thomas Suckow ab3a0f58f1 Implement AuthHandler in Kestrel 2023-05-03 21:54:11 -07:00
Thomas Suckow 97862fbeec Fix potential duplicate header crash and handling of the url slug
Fixes the run now link on a backup job
2023-05-03 21:10:19 -07:00
Russell Smith 6fb3206b22 Use 1MB default block as suggested by users.
This still allows 50 blocks for the default upload size.
It reduces the blocks to track by a factor of 10.
If you are using larger backups, you want a larger block size.

If you have small backups and it's a problem, recreating those
will take less time.
2023-04-22 16:50:48 +10:00
Thomas Suckow f0e9257a62 Mostly working. runnow doesn't work 2023-03-15 22:02:53 -07:00
Thomas Suckow 238f1dd900 Initial static files support 2023-03-14 22:05:52 -07:00
Thomas Suckow 006af8fd78 More services working (licenses, systeminfo, serverstate) 2023-03-13 20:07:49 -07:00
Thomas Suckow c318c43002 Progress on implementing legacy webserver shims 2023-03-01 21:47:31 -08:00
Thomas Suckow e5442da247 [WIP] Kestrel loads and routes loaded, shim classes not yet implemented 2023-01-29 17:29:57 -08:00
Thomas Suckow 83bc52bff4 More WIP setting up kestrel 2023-01-28 08:15:45 -08:00
Thomas Suckow 235568dade First pass at introducing kestrel and refactoring to make the RESTAPI be its own package. 2022-12-30 10:59:29 -08:00
Thomas Suckow 83cc35664b Missing file 2022-11-18 21:56:01 -08:00
Thomas Suckow 69ccc12e7d Reorganize the backends to be referenced via a single csproj
For my sanity
2022-11-18 21:55:46 -08:00
Thomas Suckow bb3ab13a8e Cleanup osx build 2022-11-18 21:41:41 -08:00
Thomas Suckow aeb4402a54 Resize the DMG before populating it 2022-11-13 13:51:37 -08:00
Thomas Suckow 2e2da4fde7 Fix file placement and plist generation 2022-11-13 13:32:47 -08:00
Thomas Suckow 4501dff4d3 Fix Path 2022-11-13 10:44:50 -08:00
Thomas Suckow 71796c6ebf Fix executable bit 2022-11-13 10:26:20 -08:00
Thomas Suckow ab805b2173 Take 1 at Duplicati DMG 2022-11-13 10:08:35 -08:00
Thomas Suckow 08472517b9 Fix tray icon issues on MacOS 2022-11-12 10:38:06 -08:00
Thomas Suckow 78197453a1 Merge remote-tracking branch master into feature/net5-avalonia
# Conflicts:
#	Duplicati CommandLine Only.sln
#	Duplicati.sln
#	Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
#	Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
#	Duplicati/CommandLine/Duplicati.CommandLine.csproj
#	Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/app.config
#	Duplicati/Library/AutoUpdater/UpdaterManager.cs
#	Duplicati/Library/Backend/Jottacloud/Duplicati.Library.Backend.Jottacloud.csproj
#	Duplicati/Library/Main/Duplicati.Library.Main.csproj
#	Duplicati/Library/Utility/Duplicati.Library.Utility.csproj
#	Duplicati/Library/Utility/Utility.cs
#	Duplicati/Server/Duplicati.Server.csproj
#	Duplicati/Server/app.config
#	Duplicati/Service/app.config
#	Duplicati/UnitTest/BackendToolTests.cs
#	Duplicati/UnitTest/Duplicati.UnitTest.csproj
#	guiTests/guiTest.py
2022-11-11 21:40:08 -08:00
Thomas Suckow 3f9263892b Disable encryption of database due to closed source 2022-11-06 22:05:36 -08:00
Thomas Suckow 0c2b3694c5 Merge branch 'feature/net5-unsplit' into feature/net5-avalonia 2022-09-29 21:39:01 -07:00
Thomas Suckow ae70cf344d give up on freebsd 2022-09-29 21:36:51 -07:00
Thomas Suckow 052b169e9e Fix verson number 2022-09-29 21:01:39 -07:00
Thomas Suckow bf3e6337b0 Try without sshfs 2022-09-28 22:15:13 -07:00
Thomas Suckow 173b6f8ef0 Update freebsd .net version 2022-09-28 21:54:20 -07:00
Thomas Suckow afa322cc59 Update freebsd action 2022-09-28 21:54:03 -07:00
Thomas Suckow 0a35243b07 macos-12 2022-09-28 21:47:22 -07:00
Thomas Suckow 8055cfb4f0 Working minimal avalonia tray icon 2022-09-28 20:44:09 -07:00
Thomas Suckow 86ceb95e28 Proof of concept to support Avalonia 2022-09-02 08:50:08 -07:00
Thomas Suckow 961b443f1f 20G Swap for freebsd
YOLO
2022-05-13 08:15:43 -07:00
Thomas Suckow cfa41434ad Add process memory usage and print more often 2022-05-13 07:54:24 -07:00
Thomas Suckow 817b1d5bc2 Try to debug time discrepency 2022-05-06 21:52:19 -07:00
Thomas Suckow 3172ec3a4b More logging in tests 2022-05-06 21:46:17 -07:00
Thomas Suckow 5956b771f0 Cleanup inconsistent overrides of test SetUp and TearDown.
Also add some memory usage diagnostics
2022-05-05 22:30:15 -07:00
Thomas SuckowandGitHub c38e654db9 Upgrade fedora to latest
.net6 is only on 34+ so jump to the latest fedora
2022-05-05 20:16:54 -07:00
Thomas SuckowandGitHub dc5750e6ab Pin ubuntu to previous LTS
Ubuntu 22 is not yet supported by .net6 due to openSSL changes.
2022-05-05 20:05:40 -07:00
Thomas Suckow e66fc1ddc8 Test name logging. 2022-05-01 22:55:03 -07:00
Thomas Suckow 9dfec79a64 Missed a spot 2022-05-01 22:17:50 -07:00
Thomas Suckow 6d617f32fc .net6.0.3 for freebsd 2022-05-01 22:15:44 -07:00
Thomas Suckow b3826237d5 Update unittest libs 2022-05-01 22:14:39 -07:00
Thomas Suckow d8fb30298d Swapfile hardmode 2022-04-12 22:28:44 -07:00
Thomas Suckow 80de20b557 More freebsd swap 2022-04-12 22:02:34 -07:00
Thomas Suckow 1af776a4d6 missed some .net6 2022-04-12 21:51:56 -07:00
Thomas Suckow 8c518f7d3a .net6 2022-04-12 21:43:50 -07:00
Thomas SuckowandGitHub 02af15d4a4 Try .net6 on freebsd 2022-04-12 21:08:46 -07:00
Thomas Suckow 06bca4b5d8 Try making test path absolute 2022-04-10 20:52:01 -07:00
Thomas Suckow 71faeb9a0e Try gzipping the logs 2022-03-14 21:07:07 -07:00
Thomas Suckow 20214f6c00 Don't delete logs after test 2022-03-13 10:22:32 -07:00
Thomas Suckow dfd210125e Move logs to folder 2022-03-13 10:02:13 -07:00
Thomas Suckow c2a3987f3a Symlink logs 2022-03-12 22:31:25 -08:00
Thomas Suckow 7a4c7b36b8 Change directory of unittest data in CI 2022-03-12 22:01:12 -08:00
Thomas Suckow 081502fc2a Logs
Stop writing test data to home folder by default
Store logs in github for inspection
Be a little less verbose
2022-03-12 21:30:16 -08:00
Thomas Suckow eba9f4545c More meesage for unit test 2022-03-12 20:28:49 -08:00
Thomas SuckowandGitHub cd71fde158 Go back to unmangled version 2022-03-08 20:13:53 -08:00
Thomas Suckow 7419df0979 use nuget.config to add freebsd repository 2022-03-05 10:17:28 -08:00
Thomas Suckow 80b19b9f8c Try to add freebsd native lib packages 2022-03-04 23:13:36 -08:00
Thomas Suckow 02f58d5186 Copy publish folder after finishing build 2022-03-03 22:32:56 -08:00
Thomas Suckow db30c5df85 Try to get freebsd to play nice 2022-03-03 22:11:17 -08:00
Thomas Suckow 1a5cca1bf7 Fix extracting version for installers 2022-03-03 21:56:58 -08:00
Thomas Suckow 26dea45698 Fix bad merge of firefox options 2022-03-03 21:50:24 -08:00
Thomas Suckow 0093561ec6 Update github actions 2022-03-03 21:31:10 -08:00
Thomas Suckow bf5b9537d8 Merge remote-tracking branch 'thomas/feature/net5-freebsd' into feature/net5-unsplit
# Conflicts:
#	Duplicati.sln
#	Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
#	Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
#	Duplicati/CommandLine/CLI/Commands.cs
#	Duplicati/CommandLine/Duplicati.CommandLine.csproj
#	Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/ImageLoader.cs
#	Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj
#	Duplicati/Library/Backend/SSHv2/packages.config
#	Duplicati/Library/Backend/Tardigrade/Duplicati.Library.Backend.Tardigrade.csproj
#	Duplicati/Library/Common/Duplicati.Library.Common.csproj
#	Duplicati/Library/SQLiteHelper/Duplicati.Library.SQLiteHelper.csproj
#	Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj
#	Duplicati/License/Duplicati.License.csproj
#	Duplicati/Server/Duplicati.Server.csproj
#	Duplicati/UnitTest/Duplicati.UnitTest.csproj
#	Duplicati/UnitTest/TestUtils.cs
#	Duplicati/UnixSupport/UnixSupport.csproj
#	Installer/Makefile/Makefile
#	guiTests/guiTest.py
2022-03-03 21:20:34 -08:00
Thomas Suckow d196e42780 Remove .net framework executables 2022-03-03 20:24:15 -08:00
Thomas SuckowandGitHub 88955a480d Test runtime 2022-03-03 19:53:43 -08:00
Thomas SuckowandGitHub a8182b2c77 ending slash 2022-03-03 19:43:01 -08:00
Thomas SuckowandGitHub a432b7fead move obj folder 2022-03-03 19:26:53 -08:00
Thomas SuckowandGitHub f5ef2d0ba2 Do everything in one command
To avoid file in use error
2022-03-02 21:23:19 -08:00
Thomas SuckowandGitHub 3ce9965c19 Try bash 2022-03-02 21:12:17 -08:00
Thomas SuckowandGitHub 996f508e3a Capitalization 2022-03-02 21:07:08 -08:00
Thomas SuckowandGitHub 437f373373 5.0.9 2022-03-02 20:46:56 -08:00
Thomas SuckowandGitHub 95ae2fdd19 sdk fixups 2022-03-02 20:27:39 -08:00
Thomas SuckowandGitHub ea16150d4f Native nupkgs 2022-03-02 19:47:56 -08:00
Thomas Suckow 15256c70ef comments 2022-03-02 18:42:42 -08:00
Thomas Suckow c2880f517b icu 2022-03-02 17:40:34 -08:00
Thomas Suckow 6dafc91239 libunwind 2022-03-02 08:33:39 -08:00
Thomas Suckow 6498c32a97 No bashisms 2022-03-02 08:14:00 -08:00
Thomas Suckow d7d9054f36 var tmp 2022-03-02 08:00:26 -08:00
Thomas Suckow 692391bd3e tmp 2022-03-02 07:47:20 -08:00
Thomas Suckow 10a57b9b5f Follow redirects 2022-03-01 21:27:42 -08:00
Thomas Suckow e898ea0745 Download outside vm 2022-03-01 21:10:27 -08:00
Thomas Suckow 2efb2543e1 install wget 2022-03-01 20:38:35 -08:00
Thomas Suckow 29b1b7097c Try freebsd build 2022-03-01 20:26:40 -08:00
Thomas Suckow d528703fe7 Merge branch 'master' into experiment/net5-split
# Conflicts:
#	.github/workflows/tests.yml
#	Duplicati.sln
#	Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
#	Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
#	Duplicati/CommandLine/Duplicati.CommandLine.csproj
#	Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
#	Duplicati/Library/Backend/AzureBlob/AzureBlobWrapper.cs
#	Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj
#	Duplicati/Library/Backend/Mega/packages.config
#	Duplicati/Library/Backend/OAuthHelper/Duplicati.Library.OAuthHelper.csproj
#	Duplicati/Library/Backend/Tardigrade/Duplicati.Library.Backend.Tardigrade.csproj
#	Duplicati/Library/Backend/Tardigrade/Properties/AssemblyInfo.cs
#	Duplicati/Library/Backend/Tardigrade/packages.config
#	Duplicati/Library/Common/Duplicati.Library.Common.csproj
#	Duplicati/Library/Common/IO/SystemIOWindows.cs
#	Duplicati/Library/Modules/Builtin/Duplicati.Library.Modules.Builtin.csproj
#	Duplicati/Library/Modules/Builtin/packages.config
#	Duplicati/Library/Utility/Utility.cs
#	Duplicati/License/Duplicati.License.csproj
#	Duplicati/Server/Duplicati.Server.csproj
#	Duplicati/Server/packages.config
#	Duplicati/UnitTest/Duplicati.UnitTest.csproj
2022-02-22 19:04:01 -08:00
Kenneth Hsu 895ab357a7 Restrict branch in GitHub test workflow. 2021-06-28 10:23:00 -07:00
Kenneth Hsu b400be18da Add GitHub workflow to run tests using .NET 5.
This fixes #4537.
2021-06-28 09:57:29 -07:00
Kenneth Hsu 30287a3eb4 Replace manual thread management with Tasks and CancellationToken.
This was causing a strange issue when testing the situation where write
privileges were removed from the local destination directory.  Instead
of catching the AccessViolationException and returning the expected exit
code of 100, the process would exit with Aborted (core dumped).

This concerns #4533.
2021-06-28 09:52:13 -07:00
Kenneth Hsu f2bcf470d2 Add factory method to get default AmazonS3Config instance.
This adds a method to get a default instance of AmazonS3Config.  This
accomplishes two key things:

1. Previously, the documentation for the default buffer size (8192) was
   inconsistent with the actual default value (65536).  This was due to
   differences in the property values betwen the instance used to
   generate the documentation, and that used in the actual backend
   client.

2. Disables the use of Amazon Resource Names (ARN).  This does not seem
   critical to our application.  Moreover, if the UseArnRegion property
   is not set, accessing it triggers an expensive operation (~30
   seconds) to get the region endpoint.  This causes the loading of the
   backend modules to take a long time and run afoul of HTTP request
   timeouts, causing the application to think that no backends are
   available.

   The previous version of the AWSSDK.S3 library that we used did not
   have this property, so this was not an issue until we started
   migrating away from .NET Framework.

This fixes #4543.
2021-06-28 09:52:13 -07:00
Kenneth Hsu 67eef2c1fd Fix path to GTK tray icons.
The use of a backslash as a path separator only works for Windows.

This fixes #4528.
2021-06-28 09:52:13 -07:00
Thomas SuckowandKenneth Hsu 69d90e8fc3 Rip out libappindicator as it isn't compatible with net5
This fixes #4529.
2021-06-28 09:52:13 -07:00
Thomas SuckowandKenneth Hsu 060b4886da Just use the nuget version of the sqlite library
This fixes #4526.
2021-06-28 09:52:13 -07:00
Kenneth Hsu f3b43d2df6 Fix GTK build.
This fixes #4527.
2021-06-28 09:44:32 -07:00
warwickmmandGitHub 48f2679391 Merge pull request #4483 from tsuckow/net5-split/more-bugfixes
This fixes some additional issues in the experimental/net5-split branch:

* Replace call to Thread.Abort.
* Fix retrieval of embedded resource.
* Replace DNS client (DnsLite doesn't work on Mac or Linux with .NET 5).
* Avoid opening terminal when running TrayIcon project on Windows.
2021-06-28 09:35:57 -07:00
Kenneth SkovhedeandGitHub dea88ee58c Merge pull request #4521 from warwickmm/use_consistent_target_framework
Use consistent target framework for .NET 5 entry executables
2021-05-29 12:14:37 +02:00
Kenneth Hsu 82f60d7989 Use consistent target frameworks for entry executables.
Previously, we would have inconsistent paths to the executables (net5
vs. net5.0).  For example,

Executables/net5/Duplicati.CommandLine.BackendTester/bin/Debug/net5.0
Executables/net5/Duplicati.CommandLine/bin/Debug/net5

With these changes, the path to the Duplicati.CommandLine executables
becomes

Executables/net5/Duplicati.CommandLine/bin/Debug/net5.0
2021-05-23 20:20:21 -07:00
Thomas Suckow 1e64788a6b Change console logs to Logger 2021-04-13 07:48:27 -07:00
Thomas Suckow 7b90ed3c5a Fix loading backup defaults after assembly rename 2021-04-11 13:37:54 -07:00
Thomas Suckow 6f3d293364 Fix trayicons opening terminal 2021-04-11 13:37:21 -07:00
Thomas Suckow 6fd696a661 Missed a thread abort 2021-04-10 13:43:19 -07:00
Thomas Suckow 1b72212533 Dnslite doesn't work on mac/linux in .net5 2021-04-10 13:39:53 -07:00
Kenneth SkovhedeandGitHub e3c96d0ee0 Merge pull request #4478 from tsuckow/net5-split/fixups
Net5 split/fixups
2021-04-09 18:10:20 +02:00
Thomas Suckow ecb0249259 dotnet no longer provides a method for a string to hashalgorithm
* Also fix up not diposing of hashers
2021-04-04 11:17:13 -07:00
Thomas Suckow d8ddd6982c Refactor VolumeHash 2021-04-04 08:28:44 -07:00
Thomas Suckow 7b760ce237 Fix accidental revert from when master was merged into the netstandard branch 2021-04-03 20:58:34 -07:00
Thomas Suckow 898193fcef For now, just interrupt since its better than NOP. 2021-04-03 20:54:47 -07:00
Thomas Suckow 0f675bc4a9 Include html in output 2021-04-03 20:47:40 -07:00
Thomas Suckow 5a034f7b6d Fix mono.posix to the netstandard version and make it a first class citizen 2021-04-03 20:38:29 -07:00
Kenneth Skovhede 4911cfdaa4 Reworked AlphaFS and AlphaVSS to use pre-built versions targeting netstandard2.0 to avoid excessive warnings on build.
Still needs to include he native files.
2021-04-03 21:50:52 +02:00
Kenneth Skovhede b550e61d9b Re-added compatibility analyzers 2021-04-03 21:49:51 +02:00
Kenneth Skovhede 557415c9ad Changed implementation to target netstandard2.0.
Added builds for .Net 4.8
2021-04-03 14:13:32 +02:00
Kenneth Skovhede 8892ff7df3 Cleaned up all .csproj files.
Moved things around to make cleaner build files.
Implementing everything with `netstandard2.1` and then thin wrapper executables using .net5
2021-04-03 13:57:02 +02:00
Thomas Suckow 425a9d23dc Fix change in sdk location 2021-04-02 18:13:06 -07:00
Thomas Suckow 842fc6dbae More execute bit 2021-04-02 07:15:56 -07:00
Thomas Suckow 11e4d35efb Fix execute bit 2021-04-02 06:54:15 -07:00
Thomas Suckow f73d736f54 Add rpm build 2021-04-02 06:52:55 -07:00
Thomas Suckow 90ac3c1cef it already is unzipped 2021-04-02 06:36:33 -07:00
Thomas Suckow 753f61ee1f Don't stop at the debugger in release builds
* Also don't show a terminal window for the trayicon
2021-04-01 21:03:11 -07:00
Thomas Suckow 6810f410d3 Fix shortcut 2021-04-01 20:31:21 -07:00
Thomas Suckow 4c6439c507 debugging 2021-04-01 20:31:20 -07:00
Thomas Suckow a7eed0a518 MSI work 2021-04-01 20:31:20 -07:00
Thomas Suckow 400fa2a7d1 MSI environment test 2021-04-01 20:31:19 -07:00
Thomas Suckow 70727b9f68 Merge remote-tracking branch 'duplicati/master'
# Conflicts:
#	.appveyor.yml
#	Duplicati.sln
#	Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
#	Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
#	Duplicati/CommandLine/Duplicati.CommandLine.csproj
#	Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
#	Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj
#	Duplicati/Library/Backend/SSHv2/packages.config
#	Duplicati/Library/Backend/Tardigrade/Duplicati.Library.Backend.Tardigrade.csproj
#	Duplicati/Library/Backend/Telegram/Duplicati.Library.Backend.Telegram.csproj
#	Duplicati/Library/Backend/Telegram/Properties/AssemblyInfo.cs
#	Duplicati/License/Duplicati.License.csproj
#	Duplicati/Server/Duplicati.Server.csproj
#	Duplicati/UnitTest/Duplicati.UnitTest.csproj
#	Duplicati/UnitTest/PurgeTesting.cs
#	Installer/fedora/duplicati-binary.spec
#	Installer/fedora/duplicati.spec
#	guiTests/guiTest.py
#	pipeline/shared/duplicati.sh
#	pipeline/stage_build/trigger.sh
#	pipeline/stage_integrationtests/job.sh
#	pipeline/stage_integrationtests/trigger.sh
#	pipeline/stage_unittests/trigger.sh
2021-04-01 20:30:19 -07:00
Kenneth Skovhede bd172d39c8 Disabled auto-updater as re-launching does not work the same way with .net5 2021-04-01 22:38:34 +02:00
Kenneth Skovhede 63d8ab7c11 Changed all non-entry methods to use netstandard2.1 2021-04-01 22:37:26 +02:00
Kenneth Skovhede abc361031c Removed unused sln 2021-04-01 15:14:59 +02:00
Kenneth Skovhede 4f565a004f Merge branch 'netstandard' of https://github.com/mnaiman/duplicati into netstandard
# Conflicts:
#	Duplicati.sln
#	Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
#	Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
#	Duplicati/CommandLine/Duplicati.CommandLine.csproj
#	Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
#	Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj
#	Duplicati/Library/Backend/SSHv2/packages.config
#	Duplicati/Library/Backend/Tardigrade/Duplicati.Library.Backend.Tardigrade.csproj
#	Duplicati/Library/Backend/Telegram/Duplicati.Library.Backend.Telegram.csproj
#	Duplicati/Library/Backend/Telegram/Properties/AssemblyInfo.cs
#	Duplicati/License/Duplicati.License.csproj
#	Duplicati/Server/Duplicati.Server.csproj
#	Duplicati/UnitTest/Duplicati.UnitTest.csproj
2021-04-01 15:08:42 +02:00
Thomas Suckow 4d6d671fdc Fix debian 2021-03-20 15:58:36 -07:00
Thomas Suckow dfa9e527bd At least make the debian build run again
The artifact is still b0rked due to some missing library that I don't understand since the fedora build works.
2021-03-19 06:43:09 -07:00
Thomas Suckow 0e227a31b9 Disable autoupdater across the board 2021-03-19 06:42:14 -07:00
Thomas Suckow 3b8d9608ef Rip out libappindicator as it isn't compatible with net5 2021-03-19 06:42:02 -07:00
Thomas Suckow a28b5c7860 Restore missing file 2021-03-06 22:12:01 -08:00
Thomas Suckow ab9e807bc0 Somewhat working Fedora rpm 2021-03-06 18:10:39 -08:00
Thomas Suckow dd399d8f2f Fedora work 2021-02-07 16:54:36 -08:00
Thomas Suckow 3056824ff1 Artifact naming 2021-01-17 10:19:42 -08:00
Thomas Suckow 46440ebf40 More greedy regex 2021-01-17 10:13:40 -08:00
Thomas Suckow acb557314f Maybe carriage return? 2021-01-17 10:09:31 -08:00
Thomas Suckow 761eacc55d Ugh 2021-01-17 09:53:09 -08:00
Thomas Suckow ffc7b165ad Why newline why 2021-01-16 16:46:45 -08:00
Thomas Suckow aad89b9bda Try to mitigate newline 2021-01-16 16:38:12 -08:00
Thomas Suckow 5e8db0cead Fix execute bit 2021-01-16 16:19:46 -08:00
Thomas Suckow bb0a6e8a12 Get debian packages building (untested) 2021-01-16 16:13:00 -08:00
Thomas Suckow cda1e2e09a Remove old build scripts 2021-01-08 08:16:30 -08:00
Thomas Suckow f424c1e999 Don't publish the unit tests 2021-01-08 07:51:13 -08:00
Thomas Suckow 32c3eb3a0e Selenium Docker Actions 2021-01-07 21:43:58 -08:00
Thomas Suckow 2db939ba6a Fix missing webroot when publishing 2021-01-07 21:40:47 -08:00
Thomas Suckow 14dbd73da2 Typo 2021-01-06 07:50:59 -08:00
Thomas Suckow 51288b85ed Test assumptiions about docker on github actions 2021-01-06 07:38:24 -08:00
Thomas Suckow 3a730741c2 change working directory 2021-01-06 07:23:16 -08:00
Thomas Suckow 096e0a46f3 Disable the updater 2021-01-05 21:20:20 -08:00
Thomas Suckow 39b79f6474 Test self contained 2021-01-05 20:44:22 -08:00
Thomas Suckow 47b3da1cd3 Python 3 2021-01-05 20:37:07 -08:00
Thomas Suckow 9d8e6014ce Its native, no .exe 2021-01-05 19:44:39 -08:00
Thomas Suckow 60e85591a9 Try to find the files. 2021-01-05 08:05:10 -08:00
Thomas Suckow cc6e404397 Try to fix paths 2021-01-05 07:39:44 -08:00
Thomas Suckow d976969deb Erronious mono 2021-01-04 21:22:57 -08:00
Thomas Suckow aa05b6bead Try to get selenium working and make the artifacts be release builds 2021-01-04 21:07:03 -08:00
Thomas Suckow dd883b8937 Fix some naming 2021-01-04 19:59:33 -08:00
Thomas Suckow 8e7f55d863 Try splitting workflow to get artifacts sooner 2021-01-04 19:52:39 -08:00
Thomas Suckow 3643862bfd More ci tweaks 2021-01-04 19:51:49 -08:00
Thomas Suckow 25217a93c1 CI script updates 2021-01-04 19:42:48 -08:00
Thomas Suckow 48f7110c0b fix publishing maybe 2021-01-04 07:35:30 -08:00
Thomas Suckow e80abca658 Try to get publishing to work despite depending on exes like dlls 2021-01-03 22:27:03 -08:00
Thomas Suckow f2d209cfaf Even more relaxed 2021-01-03 22:26:35 -08:00
Thomas Suckow 733fd712d2 Fix restore not including the runtime 2021-01-03 19:49:35 -08:00
Thomas Suckow 4cdeaa94c7 Relax unit test file time checking on osx 2021-01-03 19:49:35 -08:00
Thomas Suckow d4e613939e Debug macos time difference 2021-01-03 18:14:16 -08:00
Thomas Suckow 7400e20ff0 Try object syntax 2021-01-03 16:42:57 -08:00
Thomas Suckow d935d71d3a Set runtime when publishing 2021-01-03 15:43:59 -08:00
Thomas Suckow 7b30ef31ea Add artifacts 2021-01-03 15:20:26 -08:00
Thomas Suckow 0ee4f27ab6 Matrix build 2021-01-03 14:17:05 -08:00
Thomas Suckow 238a31fea0 FIXME: Strange time issue with backups 2021-01-03 09:40:58 -08:00
Thomas Suckow 360d819c0d Threads are not longer abortable 2021-01-03 08:54:09 -08:00
Thomas Suckow e74433aced Use nuget posix library and fold UnixSupport into the normal build. 2021-01-03 08:07:00 -08:00
Thomas Suckow b1001fcfea Move Unix Support (for file history) 2021-01-03 07:49:42 -08:00
MaxandGitHub 73d3310cf8 Merge pull request #64 from tsuckow/net5
Fix Backup job database migration
2021-01-03 13:01:17 +01:00
Thomas Suckow ef0039b8ff Update build script 2021-01-02 22:34:19 -08:00
Thomas Suckow a759995e7b Just use the nuget version of the sqlite library 2021-01-02 22:26:00 -08:00
Thomas SuckowandGitHub b1973934d7 Update .appveyor.yml 2021-01-02 21:47:00 -08:00
Thomas SuckowandGitHub 971b5bc64e Update dotnet.yml 2021-01-02 21:17:03 -08:00
Thomas SuckowandGitHub 9050e6449f Actions 2021-01-02 21:15:05 -08:00
Thomas Suckow 50bc8880ac Restore not forking when debugging.
* Fix library name mismatch preventing environmental variables from being loaded correctly
2020-12-29 10:20:19 -08:00
Thomas Suckow acea2fe10f upstream
Update Telegram SharpAESCrypt dep
Update SystemIOWindows to split the difference

# Conflicts:
#	BuildTools/AutoUpdateBuilder/AutoUpdateBuilder.csproj
#	BuildTools/AutoUpdateBuilder/packages.config
#	BuildTools/DependencyFinder/DependencyFinder.csproj
#	BuildTools/DependencyFinder/packages.config
#	BuildTools/GnupgSigningTool/GnupgSigningTool.csproj
#	BuildTools/UpdateVersionStamp/UpdateVersionStamp.csproj
#	BuildTools/UpdateVersionStamp/app.config
#	Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
#	Duplicati/CommandLine/BackendTester/app.config
#	Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
#	Duplicati/CommandLine/BackendTool/app.config
#	Duplicati/CommandLine/ConfigurationImporter/Duplicati.CommandLine.ConfigurationImporter.csproj
#	Duplicati/CommandLine/Duplicati.CommandLine.csproj
#	Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
#	Duplicati/CommandLine/RecoveryTool/packages.config
#	Duplicati/CommandLine/app.config
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/app.config
#	Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config
#	Duplicati/Library/AutoUpdater/Duplicati.Library.AutoUpdater.csproj
#	Duplicati/Library/AutoUpdater/app.config
#	Duplicati/Library/AutoUpdater/packages.config
#	Duplicati/Library/Backend/AlternativeFTP/Duplicati.Library.Backend.AlternativeFTP.csproj
#	Duplicati/Library/Backend/AlternativeFTP/app.config
#	Duplicati/Library/Backend/AlternativeFTP/packages.config
#	Duplicati/Library/Backend/AzureBlob/Duplicati.Library.Backend.AzureBlob.csproj
#	Duplicati/Library/Backend/AzureBlob/packages.config
#	Duplicati/Library/Backend/Backblaze/Duplicati.Library.Backend.Backblaze.csproj
#	Duplicati/Library/Backend/Backblaze/packages.config
#	Duplicati/Library/Backend/Box/Duplicati.Library.Backend.Box.csproj
#	Duplicati/Library/Backend/Box/packages.config
#	Duplicati/Library/Backend/CloudFiles/Duplicati.Library.Backend.CloudFiles.csproj
#	Duplicati/Library/Backend/CloudFiles/app.config
#	Duplicati/Library/Backend/Dropbox/Duplicati.Library.Backend.Dropbox.csproj
#	Duplicati/Library/Backend/Dropbox/packages.config
#	Duplicati/Library/Backend/FTP/Duplicati.Library.Backend.FTP.csproj
#	Duplicati/Library/Backend/FTP/app.config
#	Duplicati/Library/Backend/File/Duplicati.Library.Backend.File.csproj
#	Duplicati/Library/Backend/File/app.config
#	Duplicati/Library/Backend/GoogleServices/Duplicati.Library.Backend.GoogleServices.csproj
#	Duplicati/Library/Backend/GoogleServices/packages.config
#	Duplicati/Library/Backend/HubiC/Duplicati.Library.Backend.HubiC.csproj
#	Duplicati/Library/Backend/Jottacloud/Duplicati.Library.Backend.Jottacloud.csproj
#	Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj
#	Duplicati/Library/Backend/Mega/packages.config
#	Duplicati/Library/Backend/OAuthHelper/Duplicati.Library.OAuthHelper.csproj
#	Duplicati/Library/Backend/OAuthHelper/packages.config
#	Duplicati/Library/Backend/OneDrive/Duplicati.Library.Backend.OneDrive.csproj
#	Duplicati/Library/Backend/OneDrive/packages.config
#	Duplicati/Library/Backend/OpenStack/Duplicati.Library.Backend.OpenStack.csproj
#	Duplicati/Library/Backend/OpenStack/packages.config
#	Duplicati/Library/Backend/Rclone/Duplicati.Library.Backend.Rclone.csproj
#	Duplicati/Library/Backend/Rclone/packages.config
#	Duplicati/Library/Backend/S3/Duplicati.Library.Backend.S3.csproj
#	Duplicati/Library/Backend/S3/app.config
#	Duplicati/Library/Backend/S3/packages.config
#	Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj
#	Duplicati/Library/Backend/SSHv2/packages.config
#	Duplicati/Library/Backend/SharePoint/Duplicati.Library.Backend.SharePoint.csproj
#	Duplicati/Library/Backend/SharePoint/app.config
#	Duplicati/Library/Backend/Sia/Duplicati.Library.Backend.Sia.csproj
#	Duplicati/Library/Backend/Sia/packages.config
#	Duplicati/Library/Backend/TahoeLAFS/Duplicati.Library.Backend.TahoeLAFS.csproj
#	Duplicati/Library/Backend/TahoeLAFS/packages.config
#	Duplicati/Library/Backend/Tardigrade/Duplicati.Library.Backend.Tardigrade.csproj
#	Duplicati/Library/Backend/Tardigrade/packages.config
#	Duplicati/Library/Backend/WEBDAV/Duplicati.Library.Backend.WEBDAV.csproj
#	Duplicati/Library/Backend/WEBDAV/app.config
#	Duplicati/Library/Common/Duplicati.Library.Common.csproj
#	Duplicati/Library/Common/IO/SystemIOWindows.cs
#	Duplicati/Library/Common/app.config
#	Duplicati/Library/Common/packages.config
#	Duplicati/Library/Compression/Duplicati.Library.Compression.csproj
#	Duplicati/Library/Compression/app.config
#	Duplicati/Library/Compression/packages.config
#	Duplicati/Library/DynamicLoader/Duplicati.Library.DynamicLoader.csproj
#	Duplicati/Library/DynamicLoader/app.config
#	Duplicati/Library/Encryption/Duplicati.Library.Encryption.csproj
#	Duplicati/Library/Encryption/packages.config
#	Duplicati/Library/Interface/Duplicati.Library.Interface.csproj
#	Duplicati/Library/Localization/Duplicati.Library.Localization.csproj
#	Duplicati/Library/Localization/packages.config
#	Duplicati/Library/Logging/Duplicati.Library.Logging.csproj
#	Duplicati/Library/Logging/app.config
#	Duplicati/Library/Main/Duplicati.Library.Main.csproj
#	Duplicati/Library/Main/app.config
#	Duplicati/Library/Main/packages.config
#	Duplicati/Library/Modules/Builtin/Duplicati.Library.Modules.Builtin.csproj
#	Duplicati/Library/Modules/Builtin/packages.config
#	Duplicati/Library/SQLiteHelper/Duplicati.Library.SQLiteHelper.csproj
#	Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj
#	Duplicati/Library/Snapshots/app.config
#	Duplicati/Library/Snapshots/packages.config
#	Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj
#	Duplicati/Library/UsageReporter/packages.config
#	Duplicati/Library/Utility/Duplicati.Library.Utility.csproj
#	Duplicati/Library/Utility/app.config
#	Duplicati/Library/Utility/packages.config
#	Duplicati/License/Duplicati.License.csproj
#	Duplicati/Server/Duplicati.Server.Serialization/Duplicati.Server.Serialization.csproj
#	Duplicati/Server/Duplicati.Server.Serialization/packages.config
#	Duplicati/Server/Duplicati.Server.csproj
#	Duplicati/Server/app.config
#	Duplicati/Server/packages.config
#	Duplicati/Service/Duplicati.Service.csproj
#	Duplicati/Service/app.config
#	Duplicati/Tools/Duplicati.Tools.csproj
#	Duplicati/UnitTest/Duplicati.UnitTest.csproj
#	Duplicati/UnitTest/RestoreHandlerTests.cs
#	Duplicati/UnitTest/app.config
#	Duplicati/UnitTest/packages.config
#	Duplicati/WindowsService/App.config
#	Duplicati/WindowsService/WindowsService.csproj
#	Tools/SQLiteTool/App.config
#	Tools/SQLiteTool/SQLiteTool.csproj
#	thirdparty/TlsTest/TlsTest.csproj
#	thirdparty/UnixSupport/UnixSupport.csproj
#	thirdparty/mozroots/mozroots.csproj
2020-12-29 09:59:42 -08:00
Thomas Suckow 624a5d698b Add a catch to prevent the database being locked when migrations fail. 2020-12-28 12:18:58 -08:00
Thomas Suckow 7b40e8df20 Fix naming mismatch causing migrations to not be found 2020-12-28 12:17:33 -08:00
Max b008aed1f3 migrate to net5 + runnable 2020-06-03 00:00:38 +02:00
Max 3f2eb254c3 buildable again 2020-05-31 14:38:14 +02:00
Max c882953fdd upstream 2020-05-31 13:50:13 +02:00
MaxandGitHub 4c5b5dd692 Merge pull request #63 from duplicati/master
upstream
2020-05-31 13:40:29 +02:00
Max 7e2218663e Add Compat Analyzers 2019-12-25 19:08:52 +01:00
Max 4d62e9584d Upgrade of AlphaVSS 2019-12-25 18:34:40 +01:00
Max 76b191327f packages update 2 2019-12-25 18:23:23 +01:00
Max 28793ef204 packages update 2019-12-25 18:21:24 +01:00
Max 41a5591532 upstream 2019-12-25 16:34:56 +01:00
MaxandGitHub 951be5e661 Merge pull request #58 from duplicati/master
upstream
2019-12-25 16:17:28 +01:00
BlueBlock 1c28cf0b15 refactor AutoUpdater to an exe and a library 2019-09-06 16:57:44 -04:00
BlueBlock 95584c2d0f set project type to netcoreapp 2019-09-06 16:55:42 -04:00
Max 470d96e748 fixes autobuild 2019-09-05 16:33:42 +02:00
Max dd0b6add42 nuget update 2019-09-05 15:43:59 +02:00
Max 62d64c3ab0 upstream 2019-09-05 15:34:09 +02:00
MaxandGitHub 576e3702e7 Merge pull request #54 from duplicati/master
upstream
2019-09-05 15:18:56 +02:00
Max 87f9222a87 revert test changes 2019-08-03 01:27:45 +02:00
Max 8ad9f81356 test changes in unit tests 2019-08-03 01:14:56 +02:00
Max c90408aa2c newer build dependency 2019-08-03 00:57:53 +02:00
Max 74a35ded53 update to newer version 2019-08-03 00:55:20 +02:00
Max 66eee70d1e fixed some codacy findings
fix CallContext
2019-08-03 00:34:26 +02:00
Max afa2fa2572 thx BlueBlock
- add new CallContext
- fix getting embedded resources
2019-08-02 23:48:41 +02:00
Max 7b5b7f2134 upstream 2019-08-02 23:15:47 +02:00
MaxandGitHub e4364939de Merge pull request #53 from duplicati/master
upstream
2019-08-02 23:10:58 +02:00
Max 96ea8b124d upstream changes in library 2019-07-28 12:55:07 +02:00
Max 7aea21ef35 upstream 2019-07-28 12:44:20 +02:00
MaxandGitHub 54d462b263 Merge pull request #52 from duplicati/master
upstream
2019-07-28 12:38:18 +02:00
MaxandGitHub 34f874c6f0 Merge pull request #51 from duplicati/master
upstream
2019-06-07 16:45:58 +02:00
Michal Naiman f4eef557ee upstream 2019-05-07 11:48:40 +02:00
MaxandGitHub c9d8f42217 Merge pull request #50 from duplicati/master
upstream
2019-05-07 11:41:42 +02:00
Michal Naiman eff8abbeb1 UnixSupport converted 2019-05-04 09:11:41 +02:00
Michal Naiman 34805225be Debug code removed 2019-05-04 00:40:46 +02:00
Michal Naiman 13d723a026 Full port of TrayIcon to pure Win32 2019-05-04 00:03:52 +02:00
Michal Naiman ea7cbfa889 fixed packageid 2019-05-01 22:29:21 +02:00
Michal Naiman e7b1df98de first attempt to convert TrayIcon 2019-05-01 22:08:05 +02:00
Michal Naiman 84de33bd5f clean deps 2019-05-01 21:47:20 +02:00
Michal Naiman c482424b53 unnecessary deps 2019-05-01 21:38:52 +02:00
Michal Naiman 81ed86ec7d convert WindowsService 2019-05-01 21:30:22 +02:00
Michal Naiman 27671e0585 fixed Win32SystemEvents 2019-05-01 10:47:44 +02:00
Michal Naiman 787bcb57ae fixed Sharepoint backend 2019-05-01 10:29:38 +02:00
Michal Naiman c01210a443 mozroots remove 2 2019-05-01 10:11:02 +02:00
Michal Naiman 676787cebd TlsTest and mozroots remove 2019-05-01 09:45:31 +02:00
Michal Naiman ad2105aeb2 NuGet packages update 2019-05-01 09:28:46 +02:00
Michal Naiman 0cb6e4a1bf nuget upgrade 2019-05-01 08:37:22 +02:00
Michal Naiman 5a6fc4336a cleanup 2019-04-30 00:32:28 +02:00
Michal Naiman ae4174204b UnitTest dep upgrade 2019-04-30 00:26:30 +02:00
Michal Naiman cf74ae2cc3 UnitTest netcore version 2019-04-29 23:48:06 +02:00
Michal Naiman 4b2f014634 UnitTest csproj fixes 2019-04-29 23:03:21 +02:00
Michal Naiman cac6ea4679 convert UnitTest 2019-04-29 21:16:17 +02:00
Michal Naiman 0d4ded3ae2 fix build and temp logging 2019-04-29 20:47:11 +02:00
Michal Naiman 5ae4319d92 Alter to C# 7.0 feature 2019-04-29 08:22:22 +02:00
Michal Naiman 450ab23d76 Last fixes in dependencies after upstream merge 2019-04-29 01:00:40 +02:00
Michal Naiman aed2f4d5c8 Fixes related to DNC libraries interfaces 2019-04-29 00:57:02 +02:00
Michal Naiman cff004df76 fixes for AlphaFS long path 2019-04-28 23:32:30 +02:00
Michal Naiman 843b69136b convert UpdateVersion GnupgSigningTool 2019-04-28 15:21:43 +02:00
Michal Naiman 958f102e9e convert ConfigurationImporter 2019-04-28 15:14:39 +02:00
Michal Naiman 1bc1e58737 upstream 2019-04-28 13:45:26 +02:00
Michal Naiman 633f6e7de2 cosmetic fix 2019-04-28 13:34:17 +02:00
MaxandGitHub 60c99b3888 Merge pull request #49 from duplicati/master
upstream
2019-04-28 12:27:42 +02:00
Max123456 1e6ed778f5 fix for unc paths in prefixes 2019-01-11 22:15:38 +01:00
MaxandGitHub cd0335892b Merge pull request #48 from duplicati/master
upstream
2019-01-11 16:12:40 +01:00
MaxandGitHub 66c78b8f3d Merge pull request #46 from duplicati/master
upstream
2018-10-27 00:12:44 +02:00
Max 881087f968 allow projects to execute 2018-09-10 14:44:44 +02:00
Max 86d015997b Dependency info suppress 2018-09-10 14:34:20 +02:00
Max 2cac7cecd2 AlphaFS, AlphaVSS fully functional 2018-09-10 13:31:26 +02:00
Max ed9af377d2 Utility buildable 2018-09-09 21:33:32 +02:00
Max 513a4c71cf Snapshots convert 2018-09-09 21:19:41 +02:00
Max 00887055cc Utility convert
Battery status without Forms dependance
2018-09-09 20:56:07 +02:00
Max d2ed5c6b27 UpdateVersionStamp converted 2018-09-09 16:29:24 +02:00
Max 478d4565af DependencyFinder converted 2018-09-09 16:25:52 +02:00
Max c2a7bed781 AutoUpdateBuilder converted 2018-09-09 16:19:14 +02:00
Max 8ddc41fc70 cleanup 2018-09-09 16:09:35 +02:00
Max b6fc1d2b52 SQLiteTool converted 2018-09-09 16:00:08 +02:00
Max be503ea028 utility cleanup
zipfiledebugger converted
2018-09-09 15:54:14 +02:00
Max a22a7a7d24 remove of FasterHashing component 2018-09-09 14:42:40 +02:00
Max 30fab22340 unsinged whole solution 2018-09-09 14:21:55 +02:00
Max 64d8e114ff sync of cocol versions 2018-09-09 14:10:26 +02:00
Max b11f4d7cdd Merge branch 'master' into netstandard 2018-09-09 12:24:31 +02:00
MaxandGitHub 5253bc7c31 Merge pull request #45 from duplicati/master
upstream
2018-09-09 12:02:02 +02:00
Max 6971fa4614 Service 2018-06-30 02:04:02 +02:00
Max d1c20de111 Server 2018-06-30 01:57:11 +02:00
Max 989ae94bac Serialization 2018-06-30 01:29:15 +02:00
Max 860bbdd363 cleanup 2018-06-30 01:22:58 +02:00
Max 795b5c34dc Main 2018-06-30 01:18:59 +02:00
Max 4931739194 CommandLine 2018-06-30 01:08:35 +02:00
Max a741425a66 BackendTool 2018-06-30 00:33:04 +02:00
Max c181a1946d BackendTester 2018-06-30 00:27:28 +02:00
Max dd3271f685 recoverytool 2018-06-30 00:19:21 +02:00
Max 9e930acec5 modules.builtin 2018-06-30 00:01:50 +02:00
Max f1caf7ad3a upstream 2018-06-29 17:31:16 +02:00
Max e2e1ddc151 upstream 2018-06-29 17:26:53 +02:00
Max 68de4bbbde more libraries ported 2018-06-24 14:49:30 +02:00
Max 6289530f08 backend oauth TODO 2018-06-24 13:29:01 +02:00
Max e4997f1efc upstream 2018-06-24 12:49:51 +02:00
Max b6316bcc21 added libraries 2018-06-24 12:35:34 +02:00
Max 987086358d upstream 2018-03-31 17:42:53 +02:00
Max 3aeb2abf79 Duplicati.Encryption 2018-03-31 17:36:00 +02:00
Max f5672f69d9 upgrade .net to 4.6.2 2018-03-25 22:00:45 +02:00
Max cb3d830e8e dependencies corrections 2018-03-24 18:36:26 +01:00
Max d3d494b574 backends ported 2018-03-24 17:48:26 +01:00
1186 changed files with 34025 additions and 45674 deletions
-66
View File
@@ -1,66 +0,0 @@
version: 1.0.{build}
image: Visual Studio 2019
configuration: Debug
platform: Any CPU
environment:
AUTOUPDATER_Duplicati_SKIP_UPDATE: 1
COVERALLS_REPO_TOKEN:
secure: szQsrkP5rvra8L60SomD73/dFvRwot0UuyA566zqzI2qmLOr+MhLN0AyC8BTbhYY
before_build:
- ps: $env:UNITTEST_BASEFOLDER = "$Env:APPVEYOR_BUILD_FOLDER" + "\testdata"
- cmd: nuget restore Duplicati.sln
build:
project: Duplicati.sln
verbosity: minimal
test_script:
- ps: |
nuget install OpenCover -Version 4.7.922 -OutputDirectory packages
nuget install coveralls.net -Version 0.7.0 -OutputDirectory packages
nuget install NUnit.Runners -Version 3.10.0 -OutputDirectory packages
$testDir = ".\Duplicati\UnitTest\bin\Debug"
$tests = @("$testDir\Duplicati.UnitTest.dll")
$testsPassed = $true
foreach ($elem in $tests) {
$testResultsFile = "$elem" + ".xml"
.\packages\OpenCover.4.7.922\tools\OpenCover.Console.exe `
-register:user `
-target:.\packages\NUnit.ConsoleRunner.3.10.0\tools\nunit3-console.exe `
"-targetargs:""$elem"" /result:""$testResultsFile""" `
"-filter:+[Duplicati.Library.Main]* -[UnitTest]*" `
-output:opencover.xml `
-returntargetcode `
# Keep track of test failures so that we can throw an exception after
# uploading coverage and test results.
$testsPassed = $testsPassed -and $?
# Upload test results to AppVeyor.
$wc = New-Object "System.Net.WebClient"
$wc.UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\""$testResultsFile""))
}
if ($Env:COVERALLS_REPO_TOKEN) {
$revision = git rev-parse HEAD
$branch = git rev-parse --abbrev-ref HEAD
$commitAuthor = git show --quiet --format="%aN" $revision
$commitEmail = git show --quiet --format="%aE" $revision
$commitMessage = git show --quiet --format="%s" $revision
.\packages\coveralls.net.0.7.0\tools\csmacnz.Coveralls.exe `
--opencover -i opencover.xml `
--repoToken "$Env:COVERALLS_REPO_TOKEN" `
--commitId "$revision" `
--commitBranch "$branch" `
--commitAuthor "$commitAuthor" `
--commitEmail "$commitEmail" `
--commitMessage "$commitMessage" `
--useRelativePaths `
--basePath .\Duplicati\UnitTest\bin\Debug
}
if (!$testsPassed) {
throw "Tests failed."
}
+5
View File
@@ -0,0 +1,5 @@
*.csproj text
*.sh text eol=lf
#The #! in rules won't work if CRLF
/ReleaseBuilder/Resources/debian/* text eol=lf
/ReleaseBuilder/Resources/fedora/*.sh text eol=lf
-105
View File
@@ -1,105 +0,0 @@
name: Build release installers
on:
workflow_dispatch
env:
build_directory: "Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Release"
jobs:
macbuild:
name: mac build and installers
runs-on: macos-latest
strategy:
fail-fast: false
steps:
- name: Install NuGet
uses: nuget/setup-nuget@v1.1.1
- name: Checkout Source
uses: actions/checkout@v3
- name: Restore NuGet Packages
run: |
nuget restore Duplicati.sln
nuget restore "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
- name: Build Duplicati (macOS)
run: |
msbuild /property:Configuration=Release "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
RELEASE_TIMESTAMP=$(date +%Y-%m-%d)
RELEASE_TYPE="canary"
RELEASE_INC_VERSION=$(cat Updates/build_version.txt)
RELEASE_INC_VERSION=$((RELEASE_INC_VERSION+1))
RELEASE_VERSION="2.0.7.${RELEASE_INC_VERSION}"
RELEASE_NAME="${RELEASE_VERSION}_${RELEASE_TYPE}_${RELEASE_TIMESTAMP}"
echo "${RELEASE_NAME}" > "Duplicati/License/VersionTag.txt"
echo "${RELEASE_TYPE}" > "Duplicati/Library/AutoUpdater/AutoUpdateBuildChannel.txt"
mono "BuildTools/UpdateVersionStamp/bin/Release/UpdateVersionStamp.exe" --version="${RELEASE_VERSION}"
msbuild -p:DefineConstants=\"ENABLE_GTK\;XAMARIN_MAC\" -p:Configuration=Release Duplicati.sln
- name: Build installers (OSX)
run: |
Installer/OSX/artifact_mac.sh
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-mac
path: ~/artifacts/**/*
windowsbuild:
name: windows installer
runs-on: windows-latest
needs: macbuild
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.3
- name: Install NuGet
uses: nuget/setup-nuget@v1.1.1
- uses: actions/checkout@v3
- name: Retrieve mac build
uses: actions/download-artifact@v3
with:
name: build-results-mac
path: ~/macartifacts
- name: set env
run: echo "ZIPBUILDFILE=$(resolve-path ~ | select-object -expandproperty path)\macartifacts\$(get-childitem ~\macartifacts\*.zip | select-object -first 1 -expandproperty name )" >> $env:GITHUB_ENV
- name: Build installers (Windows)
run: |
echo ${{ env.ZIPBUILDFILE }}
.\\Installer\\Windows\\artifact_win.bat ${{ env.ZIPBUILDFILE }}
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-windows
path: ~/artifacts/**/*
debianbuild:
name: debian like installer
runs-on: ubuntu-latest
needs: macbuild
steps:
- uses: actions/checkout@v3
- name: Retrieve mac build
uses: actions/download-artifact@v3
with:
name: build-results-mac
path: ~/macartifacts
- name: set env
run: echo "ZIPBUILDFILE=$(ls ~/macartifacts/*.zip | tail -1)" >> $GITHUB_ENV
- name: Build installers (Deb)
run: |
echo ${{ env.ZIPBUILDFILE }}
sudo apt install debhelper
Installer/debian/artifact_deb.sh ${{ env.ZIPBUILDFILE }}
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-linux
path: ~/artifacts/**/*
-108
View File
@@ -1,108 +0,0 @@
name: Build release installers from PR
on:
pull_request:
types: [ labeled ]
env:
build_directory: "Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Release"
jobs:
macbuild:
if: ${{ github.event.label.name == 'testbuild' }}
name: mac build and installers
runs-on: macos-latest
strategy:
fail-fast: false
steps:
- name: Install NuGet
uses: nuget/setup-nuget@v1.1.1
- name: Checkout Source
uses: actions/checkout@v3
- name: Restore NuGet Packages
run: |
nuget restore Duplicati.sln
nuget restore "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
- name: Build Duplicati (macOS)
run: |
msbuild /property:Configuration=Release "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
RELEASE_TIMESTAMP=$(date +%Y-%m-%d)
RELEASE_TYPE="canary"
RELEASE_INC_VERSION=$(cat Updates/build_version.txt)
RELEASE_INC_VERSION=$((RELEASE_INC_VERSION+1))
RELEASE_VERSION="2.0.7.${RELEASE_INC_VERSION}"
RELEASE_NAME="${RELEASE_VERSION}_${RELEASE_TYPE}_${RELEASE_TIMESTAMP}"
echo "${RELEASE_NAME}" > "Duplicati/License/VersionTag.txt"
echo "${RELEASE_TYPE}" > "Duplicati/Library/AutoUpdater/AutoUpdateBuildChannel.txt"
mono "BuildTools/UpdateVersionStamp/bin/Release/UpdateVersionStamp.exe" --version="${RELEASE_VERSION}"
msbuild -p:DefineConstants=\"ENABLE_GTK\;XAMARIN_MAC\" -p:Configuration=Release Duplicati.sln
- name: Build installers (OSX)
run: |
Installer/OSX/artifact_mac.sh
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-mac
path: ~/artifacts/**/*
windowsbuild:
name: windows installer
runs-on: windows-latest
needs: macbuild
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.3
- name: Install NuGet
uses: nuget/setup-nuget@v1.1.1
- uses: actions/checkout@v3
- name: Retrieve mac build
uses: actions/download-artifact@v3
with:
name: build-results-mac
path: ~/macartifacts
- name: set env
run: echo "ZIPBUILDFILE=$(resolve-path ~ | select-object -expandproperty path)\macartifacts\$(get-childitem ~\macartifacts\*.zip | select-object -first 1 -expandproperty name )" >> $env:GITHUB_ENV
- name: Build installers (Windows)
run: |
echo ${{ env.ZIPBUILDFILE }}
.\\Installer\\Windows\\artifact_win.bat ${{ env.ZIPBUILDFILE }}
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-windows
path: ~/artifacts/**/*
debianbuild:
name: debian like installer
runs-on: ubuntu-latest
needs: macbuild
steps:
- uses: actions/checkout@v3
- name: Retrieve mac build
uses: actions/download-artifact@v3
with:
name: build-results-mac
path: ~/macartifacts
- name: set env
run: echo "ZIPBUILDFILE=$(ls ~/macartifacts/*.zip | tail -1)" >> $GITHUB_ENV
- name: Build installers (Deb)
run: |
echo ${{ env.ZIPBUILDFILE }}
sudo apt install debhelper
Installer/debian/artifact_deb.sh ${{ env.ZIPBUILDFILE }}
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-linux
path: ~/artifacts/**/*
+143
View File
@@ -0,0 +1,143 @@
name: Freebsd
on:
push:
branches: "**freebsd**"
pull_request:
branches: "**freebsd**"
jobs:
zip:
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- name: Download dotnet
# See also https://github.com/sec/dotnet-core-freebsd-source-build
# See also https://github.com/Thefrank/dotnet-freebsd-crossbuild
run: curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/v6.0.401-11/dotnet-sdk-6.0.401-freebsd-x64.tar.gz -o dn.tgz
- name: Build
id: test
uses: vmactions/freebsd-vm@v0
with:
usesh: true
# sync: sshfs
prepare: pkg install -y curl libinotify libunwind git cmake ninja bash wget icu
run: |
#!/bin/bash
set -x
set -e
pwd
ls -lah
whoami
env
freebsd-version
df -h
dmesg | grep memory
swapinfo
dd if=/dev/zero of=/root/swap1 bs=1m count=20480
chmod 0600 /root/swap1
mdconfig -a -t vnode -f /root/swap1 -u 0
swapon /dev/md0
df -h
swapinfo
export DOTNET_CLI_TELEMETRY_OPTOUT=1
BUILD_DIR=`pwd`
cd /var/tmp
mkdir dn
cd dn
echo Unpacking .NET
tar -xzf ${BUILD_DIR}/dn.tgz
cd ${BUILD_DIR}
mkdir /var/tmp/nuget
export RVERSION=v6.0.401-11
export VERSION=6.0.9
curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/${RVERSION}/Microsoft.AspNetCore.App.Runtime.freebsd-x64.${VERSION}.nupkg -o /var/tmp/nuget/Microsoft.AspNetCore.App.Runtime.freebsd-x64.${VERSION}.nupkg
curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/${RVERSION}/Microsoft.NETCore.App.Host.freebsd-x64.${VERSION}.nupkg -o /var/tmp/nuget/Microsoft.NETCore.App.Host.freebsd-x64.${VERSION}.nupkg
curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/${RVERSION}/Microsoft.NETCore.App.Runtime.freebsd-x64.${VERSION}.nupkg -o /var/tmp/nuget/Microsoft.NETCore.App.Runtime.freebsd-x64.${VERSION}.nupkg
curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/${RVERSION}/Microsoft.NETCore.App.Crossgen2.freebsd-x64.${VERSION}.nupkg -o /var/tmp/nuget/Microsoft.NETCore.App.Crossgen2.freebsd-x64.${VERSION}.nupkg
/var/tmp/dn/dotnet nuget add source /var/tmp/nuget/
cp -R `pwd` /var/tmp/build
cd /var/tmp/build
echo Restore
/var/tmp/dn/dotnet restore --runtime=freebsd-x64 Duplicati.sln
echo Build
/var/tmp/dn/dotnet build Duplicati.sln
echo Publish
/var/tmp/dn/dotnet publish -c Release --runtime=freebsd-x64 -o publish Duplicati.sln
cp -R ./publish ${BUILD_DIR}/publish
- name: Save Artifacts
uses: actions/upload-artifact@v2
with:
name: duplicati-freebsd-x64
path: publish
tests:
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- name: Download dotnet
# See also https://github.com/sec/dotnet-core-freebsd-source-build
# See also https://github.com/Thefrank/dotnet-freebsd-crossbuild
run: curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/v6.0.401-11/dotnet-sdk-6.0.401-freebsd-x64.tar.gz -o dn.tgz
- name: Run test
id: test
uses: vmactions/freebsd-vm@v0
with:
usesh: true
# sync: sshfs
prepare: pkg install -y curl libinotify libunwind git cmake ninja bash wget icu
run: |
#!/bin/bash
set -x
set -e
pwd
ls -lah
whoami
env
freebsd-version
df -h
dmesg | grep memory
swapinfo
dd if=/dev/zero of=/root/swap1 bs=1m count=20480
chmod 0600 /root/swap1
mdconfig -a -t vnode -f /root/swap1 -u 0
swapon /dev/md0
df -h
swapinfo
export DOTNET_CLI_TELEMETRY_OPTOUT=1
BUILD_DIR=`pwd`
cd /var/tmp
mkdir dn
cd dn
echo Unpacking .NET
tar -xzf ${BUILD_DIR}/dn.tgz
cd ${BUILD_DIR}
mkdir /var/tmp/nuget
export RVERSION=v6.0.401-11
export VERSION=6.0.9
curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/${RVERSION}/Microsoft.AspNetCore.App.Runtime.freebsd-x64.${VERSION}.nupkg -o /var/tmp/nuget/Microsoft.AspNetCore.App.Runtime.freebsd-x64.${VERSION}.nupkg
curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/${RVERSION}/Microsoft.NETCore.App.Host.freebsd-x64.${VERSION}.nupkg -o /var/tmp/nuget/Microsoft.NETCore.App.Host.freebsd-x64.${VERSION}.nupkg
curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/${RVERSION}/Microsoft.NETCore.App.Runtime.freebsd-x64.${VERSION}.nupkg -o /var/tmp/nuget/Microsoft.NETCore.App.Runtime.freebsd-x64.${VERSION}.nupkg
curl -L https://github.com/Thefrank/dotnet-freebsd-crossbuild/releases/download/${RVERSION}/Microsoft.NETCore.App.Crossgen2.freebsd-x64.${VERSION}.nupkg -o /var/tmp/nuget/Microsoft.NETCore.App.Crossgen2.freebsd-x64.${VERSION}.nupkg
/var/tmp/dn/dotnet nuget add source /var/tmp/nuget/
cp -R `pwd` /var/tmp/build
cd /var/tmp/build
echo Restore
/var/tmp/dn/dotnet restore --runtime=freebsd-x64 Duplicati.sln
echo Testing
mkdir -p ${BUILD_DIR}/duplicati_testdata/logs
mkdir -p /var/tmp/duplicati_testdata
ln -s ${BUILD_DIR}/duplicati_testdata/logs /var/tmp/duplicati_testdata/logs
export UNITTEST_BASEFOLDER=/var/tmp/duplicati_testdata
/var/tmp/dn/dotnet test --runtime=freebsd-x64 --verbosity minimal Duplicati.sln
- name: Archive Test Logs
if: always()
uses: actions/upload-artifact@v2
with:
name: test-logs
path: duplicati_testdata/logs/*
+3 -2
View File
@@ -8,8 +8,9 @@ jobs:
runs-on: ubuntu-latest
permissions:
issues: write
actions: write
steps:
- uses: actions/stale@v8
- uses: actions/stale@v9
with:
days-before-issue-stale: 15
days-before-issue-close: 15
@@ -22,4 +23,4 @@ jobs:
only-labels: "pending user feedback"
exempt-issue-labels: "bug,enhancement,good first issue,backend enhancement,backend issue,backup corruption,bounty,bugreport attached,core logic,docker,filters,help wanted,linux,localization,MacOS,mono,performance issue,reproduced,server side,ssl/tls issue,Synology,tests,translation,UI,windows"
repo-token: ${{ secrets.GITHUB_TOKEN }}
operations-per-run: 500
+17 -75
View File
@@ -2,9 +2,6 @@ name: Tests
on: [push, pull_request]
env:
build_directory: "Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Release"
jobs:
unit_tests:
name: Unit tests
@@ -12,84 +9,29 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Add msbuild to PATH (Windows)
if: matrix.os == 'windows-latest'
uses: microsoft/setup-msbuild@v1
- name: Set up .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.x
- name: Install NuGet
uses: nuget/setup-nuget@v1
- name: Checkout source
uses: actions/checkout@v4
- name: Checkout Source
uses: actions/checkout@v3
- name: Restore NuGet dependencies
run: dotnet restore Duplicati.sln
- name: Restore NuGet Packages
run: nuget restore Duplicati.sln
- name: Build Duplicati
run: dotnet build --no-restore Duplicati.sln
- name: Install Additional Dependencies
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get install gtk-sharp2
- name: Run unit tests
run: dotnet test --no-build --verbosity minimal Duplicati.sln
- name: Build Duplicati (Linux and macOS)
if: matrix.os != 'windows-latest'
run: msbuild -p:Configuration=Release -p:DefineConstants=ENABLE_GTK Duplicati.sln
- name: Build Duplicati (Windows)
if: matrix.os == 'windows-latest'
run: msbuild -p:Configuration=Release Duplicati.sln
- name: Run Unit Tests (Linux and macOS)
if: matrix.os != 'windows-latest'
run: |
export DEBUG_OUTPUT=1
nuget install NUnit.Runners -Version 3.12.0 -OutputDirectory nunit
mono nunit/NUnit.ConsoleRunner.3.12.0/tools/nunit3-console.exe Duplicati/UnitTest/bin/Release/Duplicati.UnitTest.dll
- name: Run Unit Tests (Windows)
if: matrix.os == 'windows-latest'
run: |
nuget install NUnit.Runners -Version 3.12.0 -OutputDirectory nunit
nunit/NUnit.ConsoleRunner.3.12.0/tools/nunit3-console.exe Duplicati/UnitTest/bin/Release/Duplicati.UnitTest.dll
ui_tests:
name: UI tests
selenium:
runs-on: ubuntu-latest
# Some of these steps duplicate those in the unit_tests job above. This
# can be cleaned up using a composite run steps action once it supports
# what we need (https://github.com/actions/runner/issues/646).
steps:
- name: Checkout Source
uses: actions/checkout@v3
- name: Install NuGet
uses: nuget/setup-nuget@v1
- name: Restore NuGet Packages
run: nuget restore Duplicati.sln
- name: Install Additional Dependencies
run: sudo apt-get install gtk-sharp2
- name: Build Duplicati
run: msbuild -p:Configuration=Release -p:DefineConstants=ENABLE_GTK Duplicati.sln
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Install dependencies
run: |
pip3 install selenium
pip3 install --upgrade urllib3
pip3 install chromedriver-autoinstaller
- name: Run UI tests
run: |
cp -r Duplicati/Server/webroot "${{ env.build_directory }}"/webroot
mono "${{ env.build_directory }}"/Duplicati.Server.exe &
sleep 30
python3 guiTests/guiTest.py --use-chrome
- uses: actions/checkout@v4
- name: Selenium
run: pipeline/selenium/test.sh
+3 -10
View File
@@ -4,24 +4,17 @@ obj/
*.userprefs
*.user
*.suo
Installer/Paraffin.exe
Installer/account_info
Duplicati/Localization/compiled
Duplicati/Localization/*/
Duplicati/Localization/*.diff.csv
Duplicati/Localization/*.new.csv
Duplicati/Localization/*.updated.csv
Duplicati/Localization/report.*.xml
Installer/incLocFiles.*.wxs
Duplicati/Server/webroot/extjs-*
Installer/binfiles.wxs
Installer/generated-keys.xml
Installer/oem
Updates/build
packages
changelog-news.txt
binfiles.wxs
.idea/
.vs/
Installer/debian/*.buildinfo
/publish/
ReleaseBuilder/build-temp/
ReleaseBuilder/Resources/Windows/binfiles.wxs
-83
View File
@@ -1,83 +0,0 @@
language: minimal
services: docker
before_install:
- sudo apt-get install moreutils
- set -o pipefail
addons:
coverity_scan:
project:
name: "duplicati/duplicati"
description: "Duplicati Build submitted via Travis CI"
notification_email: kenneth@duplicati.com
build_command_prepend: "msbuild /t:Clean"
build_command: "msbuild /t:Rebuild"
branch_pattern: coverity_scan
env:
global:
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
- secure: "ijaQDcVcMo/utuP514FiDZVGR5LJbATWmYDmgRIIaI0YG2Rk6uuJp9XXDXr8sx66JWttPGgs7Htqfy50VKHdr7nsfyCQCRNGmqF+OJeUgAQMj5spxn9A7PZY9+GVhnXoJ06wvYjCv5MPeLBMDK/KpIM5Ny5IG+TKzQy4U7Dyg0riMUT61aqzxSjTGfHZPmaqBICJTzsRmeGHglemFUz/1B4NAN+IeAtXoH9YIfA2LjJfYmMLckPgFQLKN/tQRaGPWXh77y0qVgA++K8UVu5W3yGo3JXBPDdabGgKs9BPlfN5/Ixnkcy6ekAubDA/Aspur9x7/szj4/AnGMY6frNB33nQcnJQZ/51GYKr6CXCmjoJQuWc8ZKdEMqDn3w/kyEzvluSjAsJNRVboeWPE4VfpAeUBsjQ+TuEQi8WXhN8VJgZV7yCkVlZTVbhtOxMPsBiFb74lpWC2iQuWLJv9ED6vyXZVzZhNtfjXNXNZzIwYxbcd7I0ZQ8fmDstFnvBJveJby2ZRpECXTbc03eIUq1SAaVJJY2r47RD1PwVqM3xvUTljIqtKdyIz915mEOjqG1BnCDaiGHYJ4byuDDeIUZO9X70s60Gh4hupZA2Ruup0v7SfYgkto6aNcStd0NYd716Vd7hqXNTp6nu01L5YYJDY4h5sHyBXVXbxCKlUb01kUw="
- USAGEREPORTER_Duplicati_LEVEL=none
- AUTOUPDATER_Duplicati_SKIP_UPDATE=1
- BUILD_DIR=${TRAVIS_BUILD_DIR}/../.build
- TEST_DIR=${TRAVIS_BUILD_DIR}/../.test
- ROOT_DIR="$TRAVIS_BUILD_DIR"
# matrix expansion within jobs would be good:
# https://github.com/travis-ci/travis-ci/issues/8295
# There is one cache per branch, so concurrent builds on different branches possible!
# DO NOT SET ENVIRONMENT VARIABLES WITHIN JOBS, OR CACHES WILL NOT BE SHARED AMONGST JOBS!
jobs:
include:
- stage: build
cache:
directories:
- $BUILD_DIR
script:
- ${ROOT_DIR}/pipeline/jobs/build_job.sh
- stage: tests
cache:
directories:
- $BUILD_DIR
script:
- ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories BulkNormal
- stage: tests
cache:
directories:
- $BUILD_DIR
script:
- ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories BulkNoSize
- stage: tests
cache:
directories:
- $BUILD_DIR
script:
- ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories SVNDataLong,SVNData,RecoveryTool,ProblematicPath,SymLink
- stage: tests
cache:
directories:
- $BUILD_DIR
script:
- travis_wait ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Border
- stage: tests
cache:
directories:
- $BUILD_DIR
script:
- ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Filter,Targeted,Purge,Serialization,WebApi,Utility,UriUtility,IO,ImportExport,Disruption,RestoreHandler,RepairHandler,DeleteHandler,Controller
- stage: tests
cache:
directories:
- $BUILD_DIR
script:
- ${ROOT_DIR}/pipeline/jobs/selenium_job.sh
addons:
sauce_connect:
username: $SAUCE_USERNAME
access_key: $SAUCE_ACCESS_KEY
+81
View File
@@ -0,0 +1,81 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch TrayIcon executable",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Executables/net8/Duplicati.GUI.TrayIcon/bin/Debug/net8.0/Duplicati.GUI.TrayIcon",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Launch Server executable",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Executables/net8/Duplicati.Server/bin/Debug/net8.0/Duplicati.Server",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Launch CommandLine executable",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Executables/net8/Duplicati.CommandLine/bin/Debug/net8.0/Duplicati.CommandLine",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Launch AutoUpdater executable",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Executables/net8/Duplicati.CommandLine.AutoUpdater/bin/Debug/net8.0/Duplicati.CommandLine.AutoUpdater",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Launch ConfigurationImporter executable",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Executables/net8/Duplicati.CommandLine.ConfigurationImporter/bin/Debug/net8.0/Duplicati.CommandLine.ConfigurationImporter",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Launch RecoveryTool executable",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Executables/net8/Duplicati.CommandLine.RecoveryTool/bin/Debug/net8.0/Duplicati.CommandLine.RecoveryTool",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "C#: Duplicati.GUI.TrayIcon Debug",
"type": "dotnet",
"request": "launch",
"projectPath": "${workspaceFolder}/Executables/net8/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj"
}
]
}
+24
View File
@@ -0,0 +1,24 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "shell",
"args": [
"build",
// Ask dotnet build to generate full paths for file names.
"/property:GenerateFullPaths=true",
// Do not generate summary otherwise it leads to duplicate errors in Problems panel
"/consoleloggerparameters:NoSummary"
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
}
]
}
@@ -1,77 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{17E3EB29-87FD-4BE9-A531-8DAD8B295494}</ProjectGuid>
<OutputType>Exe</OutputType>
<Prefer32Bit>False</Prefer32Bit>
<RootNamespace>AutoUpdateBuilder</RootNamespace>
<AssemblyName>AutoUpdateBuilder</AssemblyName>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Program.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\..\Duplicati\Library\Compression\Duplicati.Library.Compression.csproj">
<Project>{19ECCE09-B5EB-406C-8C57-BAC66997D469}</Project>
<Name>Duplicati.Library.Compression</Name>
</ProjectReference>
<ProjectReference Include="..\..\Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj">
<Project>{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}</Project>
<Name>Duplicati.Library.Encryption</Name>
</ProjectReference>
<ProjectReference Include="..\..\Duplicati\Library\Interface\Duplicati.Library.Interface.csproj">
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
<Name>Duplicati.Library.Interface</Name>
</ProjectReference>
<ProjectReference Include="..\..\Duplicati\Library\Logging\Duplicati.Library.Logging.csproj">
<Project>{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}</Project>
<Name>Duplicati.Library.Logging</Name>
</ProjectReference>
<ProjectReference Include="..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
</ProjectReference>
<ProjectReference Include="..\..\Duplicati\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj">
<Project>{7E119745-1F62-43F0-936C-F312A1912C0B}</Project>
<Name>Duplicati.Library.AutoUpdater</Name>
</ProjectReference>
<ProjectReference Include="..\..\Duplicati\License\Duplicati.License.csproj">
<Project>{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}</Project>
<Name>Duplicati.License</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
</Project>
@@ -1,74 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoUpdateBuilder", "AutoUpdateBuilder.csproj", "{17E3EB29-87FD-4BE9-A531-8DAD8B295494}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Compression", "..\..\Duplicati\Library\Compression\Duplicati.Library.Compression.csproj", "{19ECCE09-B5EB-406C-8C57-BAC66997D469}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Interface", "..\..\Duplicati\Library\Interface\Duplicati.Library.Interface.csproj", "{C5899F45-B0FF-483C-9D38-24A9FCAAB237}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Logging", "..\..\Duplicati\Library\Logging\Duplicati.Library.Logging.csproj", "{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Encryption", "..\..\Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj", "{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.AutoUpdater", "..\..\Duplicati\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj", "{7E119745-1F62-43F0-936C-F312A1912C0B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.License", "..\..\Duplicati\License\Duplicati.License.csproj", "{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Localization", "..\..\Duplicati\Library\Localization\Duplicati.Library.Localization.csproj", "{B68F2214-951F-4F78-8488-66E1ED3F50BF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Common", "..\..\Duplicati\Library\Common\Duplicati.Library.Common.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{17E3EB29-87FD-4BE9-A531-8DAD8B295494}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17E3EB29-87FD-4BE9-A531-8DAD8B295494}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17E3EB29-87FD-4BE9-A531-8DAD8B295494}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17E3EB29-87FD-4BE9-A531-8DAD8B295494}.Release|Any CPU.Build.0 = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.Build.0 = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.Build.0 = Release|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Release|Any CPU.Build.0 = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.Build.0 = Release|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Release|Any CPU.Build.0 = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.Build.0 = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.Build.0 = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = AutoUpdateBuilder.csproj
EndGlobalSection
EndGlobal
-184
View File
@@ -1,184 +0,0 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
namespace AutoUpdateBuilder
{
public class Program
{
private static RSACryptoServiceProvider privkey;
private static string keyfile;
private static string keyfilepassword;
private static void CompareToManifestPublicKey()
{
if (Duplicati.Library.AutoUpdater.AutoUpdateSettings.SignKey == null || privkey.ToXmlString(false) != Duplicati.Library.AutoUpdater.AutoUpdateSettings.SignKey.ToXmlString(false))
{
Console.WriteLine("The public key in the project is not the same as the public key from the file");
Console.WriteLine("Try setting the key to: ");
Console.WriteLine(privkey.ToXmlString(false));
System.Environment.Exit(5);
}
}
private static void LoadKeyFromFile()
{
using (var enc = new Duplicati.Library.Encryption.AESEncryption(keyfilepassword, new Dictionary<string, string>()))
using (var ms = new System.IO.MemoryStream())
using (var fs = System.IO.File.OpenRead(keyfile))
{
enc.Decrypt(fs, ms);
ms.Position = 0;
using (var sr = new System.IO.StreamReader(ms))
privkey.FromXmlString(sr.ReadToEnd());
}
}
public static int Main(string[] _args)
{
var args = new List<string>(_args);
var opts = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
opts.TryGetValue("input", out string inputfolder);
opts.TryGetValue("output", out string outputfolder);
opts.TryGetValue("allow-new-key", out string allowNewKey);
opts.TryGetValue("keyfile", out keyfile);
opts.TryGetValue("manifest", out string manifestfile);
opts.TryGetValue("keyfile-password", out keyfilepassword);
var usedoptions = new [] { "allow-new-key", "input", "output", "keyfile", "manifest", "keyfile-password" };
if (string.IsNullOrWhiteSpace(inputfolder))
{
Console.WriteLine("Missing input folder");
return 4;
}
if (string.IsNullOrWhiteSpace(outputfolder))
{
Console.WriteLine("Missing output folder");
return 4;
}
if (string.IsNullOrWhiteSpace(keyfile))
{
Console.WriteLine("Missing keyfile");
return 4;
}
if (!System.IO.Directory.Exists(inputfolder))
{
Console.WriteLine("Input folder not found");
return 4;
}
if (string.IsNullOrWhiteSpace(keyfilepassword))
{
Console.WriteLine("Enter keyfile passphrase: ");
keyfilepassword = Console.ReadLine().Trim();
}
if (!System.IO.File.Exists(keyfile))
{
Console.WriteLine("Keyfile not found, creating new");
var newkey = RSA.Create().ToXmlString(true);
using (var enc = new Duplicati.Library.Encryption.AESEncryption(keyfilepassword, new Dictionary<string, string>()))
using (var fs = System.IO.File.OpenWrite(keyfile))
using (var ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(newkey)))
enc.Encrypt(ms, fs);
}
if (!System.IO.Directory.Exists(outputfolder))
System.IO.Directory.CreateDirectory(outputfolder);
privkey = (RSACryptoServiceProvider) RSA.Create();
LoadKeyFromFile();
if (!Boolean.TryParse(allowNewKey, out Boolean newKeyAllowed) || !newKeyAllowed)
{
CompareToManifestPublicKey();
}
Duplicati.Library.AutoUpdater.UpdateInfo updateInfo;
using (var fs = System.IO.File.OpenRead(manifestfile))
using (var sr = new System.IO.StreamReader(fs))
using (var jr = new Newtonsoft.Json.JsonTextReader(sr))
updateInfo = new Newtonsoft.Json.JsonSerializer().Deserialize<Duplicati.Library.AutoUpdater.UpdateInfo>(jr);
var isopts = new Dictionary<string, string>(opts, StringComparer.InvariantCultureIgnoreCase);
foreach (var usedopt in usedoptions)
{
isopts.Remove(usedopt);
}
foreach (var k in updateInfo.GetType().GetFields())
{
if (!isopts.ContainsKey(k.Name))
{
continue;
}
try
{
//Console.WriteLine("Setting {0} to {1}", k.Name, isopts[k.Name]);
if (k.FieldType == typeof(string[]))
k.SetValue(updateInfo, isopts[k.Name].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
else if (k.FieldType == typeof(Version))
k.SetValue(updateInfo, new Version(isopts[k.Name]));
else if (k.FieldType == typeof(int))
k.SetValue(updateInfo, int.Parse(isopts[k.Name]));
else if (k.FieldType == typeof(long))
k.SetValue(updateInfo, long.Parse(isopts[k.Name]));
else
k.SetValue(updateInfo, isopts[k.Name]);
}
catch (Exception ex)
{
Console.WriteLine("Failed setting {0} to {1}: {2}", k.Name, isopts[k.Name], ex.Message);
}
isopts.Remove(k.Name);
}
foreach (var opt in isopts)
{
Console.WriteLine("Warning! unused option: {0} = {1}", opt.Key, opt.Value);
}
using (var tf = new Duplicati.Library.Utility.TempFile())
{
using (var fs = System.IO.File.OpenWrite(tf))
using (var tw = new System.IO.StreamWriter(fs))
new Newtonsoft.Json.JsonSerializer().Serialize(tw, updateInfo);
Duplicati.Library.AutoUpdater.UpdaterManager.CreateUpdatePackage(privkey, inputfolder, outputfolder, tf);
}
return 0;
}
}
}
@@ -1,27 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("AutoUpdateBuilder")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("2.0.0.7")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]
-3
View File
@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/></startup></configuration>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.2" targetFramework="net471" />
</packages>
@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{3E891818-579A-4C06-8066-4C702BFA5921}</ProjectGuid>
<OutputType>Exe</OutputType>
<Prefer32Bit>False</Prefer32Bit>
<RootNamespace>DependencyFinder</RootNamespace>
<AssemblyName>DependencyFinder</AssemblyName>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<ConsolePause>false</ConsolePause>
<Commandlineparameters>../../../../Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug</Commandlineparameters>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Rocks, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
</Project>
@@ -1,17 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DependencyFinder", "DependencyFinder.csproj", "{3E891818-579A-4C06-8066-4C702BFA5921}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3E891818-579A-4C06-8066-4C702BFA5921}.Debug|x86.ActiveCfg = Debug|x86
{3E891818-579A-4C06-8066-4C702BFA5921}.Debug|x86.Build.0 = Debug|x86
{3E891818-579A-4C06-8066-4C702BFA5921}.Release|x86.ActiveCfg = Release|x86
{3E891818-579A-4C06-8066-4C702BFA5921}.Release|x86.Build.0 = Release|x86
EndGlobalSection
EndGlobal
-85
View File
@@ -1,85 +0,0 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using Mono.Cecil;
using System.IO;
using System.Linq;
namespace DependencyFinder
{
class MainClass
{
public static void Main(string[] args)
{
var lst =
Directory.EnumerateFiles(args[0], "*.exe", SearchOption.AllDirectories).Union(
Directory.EnumerateFiles(args[0], "*.dll", SearchOption.AllDirectories))
.Select(x => {
try { return AssemblyDefinition.ReadAssembly(x); }
catch { return null; }
}).Where(x => x != null)
.Distinct();
PoC(lst, Console.Out, new [] { args[0] });
}
//Adapted from: https://stackoverflow.com/questions/9262464/tool-to-show-assembly-dependencies
public static void PoC(IEnumerable<AssemblyDefinition> assemblies, TextWriter writer, IEnumerable<string> searchfolders)
{
var resolver = new DefaultAssemblyResolver();
searchfolders.ToList().ForEach(x => resolver.AddSearchDirectory(x));
//writer.WriteLine("digraph Dependencies {");
var loaded = assemblies
.SelectMany(a => a.Modules.Cast<ModuleDefinition>())
.SelectMany(m => m.AssemblyReferences.Cast<AssemblyNameReference>())
.Distinct()
.Select(asm => {
var dllname = asm.Name + ".dll";
//Console.WriteLine("Probing for {0}", dllname);
try { return AssemblyDefinition.ReadAssembly(dllname); }
catch { }
try { return resolver.Resolve(asm.FullName); }
catch { }
return null;
})
.Where(assembly => assembly != null)
.ToList();
//loaded.ForEach(a => a.MainModule.ReadSymbols());
loaded.Select(x => x.FullName).Distinct().OrderBy(x => x).ToList().ForEach(x => writer.WriteLine("{0}", x));
/*loaded.ForEach(a =>
{
foreach (var r in a.MainModule.AssemblyReferences.Cast<AssemblyNameReference>())
writer.WriteLine(@"""{0}"" -> ""{1}"";", r.Name, a.Name.Name);
} );*/
//writer.WriteLine("}");
}
}
}
@@ -1,27 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("DependencyFinder")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("kenneth")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("2.0.0.7")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]
-3
View File
@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/></startup></configuration>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net471" />
</packages>
@@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{72B910F2-8E80-4955-A0D6-ED4C35CEE665}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>GnupgSigningTool</RootNamespace>
<AssemblyName>GnupgSigningTool</AssemblyName>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup>
<StartupObject>
</StartupObject>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj">
<Project>{2cf2d90e-c25b-47ad-91e0-98451bab8058}</Project>
<Name>Duplicati.Library.Encryption</Name>
</ProjectReference>
<ProjectReference Include="..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
</ProjectReference>
<ProjectReference Include="..\..\Duplicati\Library\Interface\Duplicati.Library.Interface.csproj">
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
<Name>Duplicati.Library.Interface</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
@@ -1,42 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29123.88
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GnupgSigningTool", "GnupgSigningTool.csproj", "{72B910F2-8E80-4955-A0D6-ED4C35CEE665}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Encryption", "..\..\Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj", "{2CF2D90E-C25B-47AD-91E0-98451BAB8058}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Interface", "..\..\Duplicati\Library\Interface\Duplicati.Library.Interface.csproj", "{C5899F45-B0FF-483C-9D38-24A9FCAAB237}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{72B910F2-8E80-4955-A0D6-ED4C35CEE665}.Debug|x86.ActiveCfg = Debug|x86
{72B910F2-8E80-4955-A0D6-ED4C35CEE665}.Debug|x86.Build.0 = Debug|x86
{72B910F2-8E80-4955-A0D6-ED4C35CEE665}.Release|x86.ActiveCfg = Release|x86
{72B910F2-8E80-4955-A0D6-ED4C35CEE665}.Release|x86.Build.0 = Release|x86
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|x86.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|x86.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.Build.0 = Release|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Debug|x86.ActiveCfg = Debug|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Debug|x86.Build.0 = Debug|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Release|x86.ActiveCfg = Release|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Release|x86.Build.0 = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.ActiveCfg = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.Build.0 = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.ActiveCfg = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {71CC6B1F-7F52-4059-8761-30B3D0501ECC}
EndGlobalSection
EndGlobal
-128
View File
@@ -1,128 +0,0 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace GnupgSigningTool
{
public static class Program
{
private static string keyfilepassword;
private static string gpgkeypassphrase;
private static string gpgkeyfile;
private static string gpgpath;
private static string gpgkeyid;
private static bool useArmor;
private static string inputFile;
private static string signatureFile;
private static void SpawnGPG()
{
var armorOption = useArmor ? "--armor" : "";
var gpgArgument = string.Format("--pinentry-mode loopback --passphrase-fd 0 --batch --yes {0} -u \"{1}\" --output \"{2}\" --detach-sig \"{3}\"",
armorOption,
gpgkeyid,
signatureFile,
inputFile);
var proc = System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = gpgpath,
Arguments = gpgArgument,
RedirectStandardInput = true,
UseShellExecute = false
});
proc.StandardInput.WriteLine(gpgkeypassphrase);
proc.WaitForExit();
}
private static void LoadGPGKeyIdAndPassphrase()
{
using (var enc = new Duplicati.Library.Encryption.AESEncryption(keyfilepassword, new Dictionary<string, string>()))
using (var ms = new System.IO.MemoryStream())
using (var fs = System.IO.File.OpenRead(gpgkeyfile))
{
try
{
enc.Decrypt(fs, ms);
}
catch (System.Security.Cryptography.CryptographicException e)
{
throw new ArgumentException("Failed to decrypt gpg secret credentials file: {0}\n", e.Message);
}
ms.Position = 0;
using (var sr = new System.IO.StreamReader(ms))
{
var lines = sr.ReadToEnd().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
gpgkeyid = lines[0];
gpgkeypassphrase = lines[1];
}
}
}
public static void Main(string[] _args)
{
var args = new List<string>(_args);
var opts = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
opts.TryGetValue("inputfile", out inputFile);
opts.TryGetValue("signaturefile", out signatureFile);
opts.TryGetValue("keyfile-password", out keyfilepassword);
opts.TryGetValue("gpgkeyfile", out gpgkeyfile);
opts.TryGetValue("gpgpath", out gpgpath);
opts.TryGetValue("armor", out string armor);
useArmor = Boolean.TryParse(armor, out useArmor) && useArmor;
if (string.IsNullOrWhiteSpace(gpgkeyfile))
{
throw new ArgumentException("No gpgfile with encrypted credentials specified.");
}
if (!System.IO.File.Exists(gpgkeyfile))
{
throw new ArgumentException("Specified file with encrypted gpg credentials not found.");
}
LoadGPGKeyIdAndPassphrase();
if (gpgkeyid is null || gpgkeypassphrase is null)
{
throw new ArgumentException("Could not fetch gpg key id or gpg passphrase.");
}
gpgpath = gpgpath ?? Duplicati.Library.Encryption.GPGEncryption.GetGpgProgramPath();
SpawnGPG();
}
}
}
-3
View File
@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/></startup></configuration>
+13 -11
View File
@@ -1,11 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>license_upgrader</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>license_upgrader</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Copyright>Copyright © 2024 Team Duplicati, MIT license</Copyright>
</PropertyGroup>
</Project>
-131
View File
@@ -1,131 +0,0 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace UpdateVersionStamp
{
public static class Program
{
private static readonly string DIR_SEP = Path.DirectorySeparatorChar.ToString();
private static readonly Dictionary<string, Regex> FILEMAP;
static Program()
{
var versionre = @"(?<version>\d+\.\d+\.(\*|(\d+(\.(\*|\d+)))?))";
FILEMAP = new Dictionary<string, Regex>(StringComparer.InvariantCultureIgnoreCase);
FILEMAP.Add("AssemblyInfo.cs", new Regex(@"(\[assembly\: AssemblyVersion\(\""" + versionre + @"""\)\])|(\[assembly\: AssemblyFileVersion\(\""" + versionre + @"\""\)\])|(\[assembly\: AssemblyFileVersionAttribute\(\""" + versionre + @"\""\)\])"));
FILEMAP.Add("UpgradeData.wxi", new Regex(@"\<\?define ProductVersion\=\""" + versionre + @"\"" \?\>"));
FILEMAP.Add("AssemblyRedirects.xml", new Regex(@"newVersion\=\""" + versionre + @"\"""));
FILEMAP.Add("index.html", new Regex(@"\?v\=" + versionre));
FILEMAP.Add("login.html", new Regex(@"\?v\=" + versionre));
FILEMAP.Add("app.js", new Regex(@"\?v\=" + versionre));
}
private class Options
{
public string sourcefolder = Path.GetFullPath(Environment.CurrentDirectory);
public string ignorefilter = null;
public string version = null;
public string versiontag = null;
public void Fixup()
{
sourcefolder = Duplicati.Library.Common.IO.Util.AppendDirSeparator(System.IO.Path.GetFullPath(sourcefolder.Replace("/", DIR_SEP)));
if (ignorefilter != null)
ignorefilter =ignorefilter.Replace("/", DIR_SEP);
}
}
public static void Main(string[] _args)
{
List<string> args = new List<string>(_args);
Dictionary<string, string> options = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
Options opt = new Options();
foreach (FieldInfo fi in opt.GetType().GetFields())
if (options.ContainsKey(fi.Name))
fi.SetValue(opt, options[fi.Name]);
opt.Fixup();
Duplicati.Library.Utility.IFilter filter = null;
if (!string.IsNullOrEmpty(opt.ignorefilter))
filter = new Duplicati.Library.Utility.FilterExpression(opt.ignorefilter, false);
Func<string, bool> isFile = (string x) => !x.EndsWith(DIR_SEP);
var paths = Duplicati.Library.Utility.Utility.EnumerateFileSystemEntries(opt.sourcefolder)
.Where(x => Duplicati.Library.Utility.FilterExpression.Matches(filter, x))
.Where(x => isFile(x) && FILEMAP.ContainsKey(Path.GetFileName(x)))
.Select(x =>
{
var m = FILEMAP[Path.GetFileName(x)].Match(File.ReadAllText(x));
return m.Success ?
new { File = x, Version = new Version(m.Groups["version"].Value.Replace("*", "0")), Display = m.Groups["version"].Value }
: null;
})
.Where(x => x != null)
.ToArray(); //No need to re-eval
if (paths.Count() == 0)
{
Console.WriteLine("No files found to update...");
return;
}
foreach (var p in paths)
Console.WriteLine("{0}\t:{1}", p.Display, p.File);
if (string.IsNullOrWhiteSpace(opt.version))
{
var maxv = paths.Select(x => x.Version).Max();
opt.version = new Version(
maxv.Major,
maxv.Minor,
maxv.Build,
maxv.Revision).ToString();
}
//Sanity check
var nv = new Version(opt.version).ToString(4);
foreach (var p in paths)
{
var re = FILEMAP[Path.GetFileName(p.File)];
var txt = File.ReadAllText(p.File);
//var m = re.Match(txt).Groups["version"];
txt = re.Replace(txt, (m) => {
var t = m.Groups["version"];
return m.Value.Replace(t.Value, nv);
});
File.WriteAllText(p.File, txt);
}
Console.WriteLine("Updated {0} files to version {1}", paths.Count(), opt.version);
}
}
}
@@ -1,22 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("UpdateVersionStamp")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("2.0.0.7")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]
@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1920C3B0-98A0-410F-8972-9C19FA616FE5}</ProjectGuid>
<OutputType>Exe</OutputType>
<Prefer32Bit>False</Prefer32Bit>
<RootNamespace>UpdateVersionStamp</RootNamespace>
<AssemblyName>UpdateVersionStamp</AssemblyName>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<Commandlineparameters>--sourcefolder=../.. --version=2.0.0.0 --version-tag=20140405</Commandlineparameters>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
</ProjectReference>
<ProjectReference Include="..\..\Duplicati\Library\Common\Duplicati.Library.Common.csproj">
<Project>{D63E53E4-A458-4C2F-914D-92F715F58ACF}</Project>
<Name>Duplicati.Library.Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
</Project>
@@ -1,35 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateVersionStamp", "UpdateVersionStamp.csproj", "{1920C3B0-98A0-410F-8972-9C19FA616FE5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Common", "..\..\Duplicati\Library\Common\Duplicati.Library.Common.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1920C3B0-98A0-410F-8972-9C19FA616FE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1920C3B0-98A0-410F-8972-9C19FA616FE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1920C3B0-98A0-410F-8972-9C19FA616FE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1920C3B0-98A0-410F-8972-9C19FA616FE5}.Release|Any CPU.Build.0 = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = UpdateVersionStamp.csproj
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
-3
View File
@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/></startup></configuration>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NGettext" version="0.6.4" targetFramework="net471" />
</packages>
-334
View File
@@ -1,334 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Main", "Duplicati\Library\Main\Duplicati.Library.Main.csproj", "{10D2D1B7-C664-41D8-9B3A-00040C3D421B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.File", "Duplicati\Library\Backend\File\Duplicati.Library.Backend.File.csproj", "{FC9B7611-836F-4127-8B44-A7C31F506807}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Compression", "Duplicati\Library\Compression\Duplicati.Library.Compression.csproj", "{19ECCE09-B5EB-406C-8C57-BAC66997D469}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Encryption", "Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj", "{2CF2D90E-C25B-47AD-91E0-98451BAB8058}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Logging", "Duplicati\Library\Logging\Duplicati.Library.Logging.csproj", "{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine", "Duplicati\CommandLine\Duplicati.CommandLine.csproj", "{81765A64-3661-4E3E-B850-2F6F87A51F74}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Interface", "Duplicati\Library\Interface\Duplicati.Library.Interface.csproj", "{C5899F45-B0FF-483C-9D38-24A9FCAAB237}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.DynamicLoader", "Duplicati\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj", "{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Snapshots", "Duplicati\Library\Snapshots\Duplicati.Library.Snapshots.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Modules.Builtin", "Duplicati\Library\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj", "{52826615-7964-47FE-B4B3-1B2DBDF605B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.License", "Duplicati\License\Duplicati.License.csproj", "{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.SSHv2", "Duplicati\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj", "{FF2BF37C-E502-4C98-BEA0-701671DDFA08}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.WEBDAV", "Duplicati\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj", "{BAE27510-8B5D-44B2-B33E-372A98908041}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.OneDrive", "Duplicati\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj", "{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.TahoeLAFS", "Duplicati\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj", "{C0270709-2A40-43B5-8CF1-69581B9FA2A1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.CloudFiles", "Duplicati\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj", "{1BFAE226-8364-4086-825C-BB83F6F3EE4C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.FTP", "Duplicati\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj", "{F61679A9-E5DE-468A-B5A4-05F92D0143D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.S3", "Duplicati\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj", "{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AzureBlob", "Duplicati\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj", "{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Localization", "Duplicati\Library\Localization\Duplicati.Library.Localization.csproj", "{B68F2214-951F-4F78-8488-66E1ED3F50BF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.AutoUpdater", "Duplicati\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj", "{7E119745-1F62-43F0-936C-F312A1912C0B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.SQLiteHelper", "Duplicati\Library\SQLiteHelper\Duplicati.Library.SQLiteHelper.csproj", "{2C838169-B187-4B09-8768-1C24C2521C8D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.UsageReporter", "Duplicati\Library\UsageReporter\Duplicati.Library.UsageReporter.csproj", "{BB014EA5-CE2C-4444-8D30-38983A0E8553}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.OAuthHelper", "Duplicati\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj", "{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.BackendTool", "Duplicati\CommandLine\BackendTool\Duplicati.CommandLine.BackendTool.csproj", "{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.BackendTester", "Duplicati\CommandLine\BackendTester\Duplicati.CommandLine.BackendTester.csproj", "{E7280DCA-7776-4A73-B9B5-41FD77FC8799}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.GoogleServices", "Duplicati\Library\Backend\GoogleServices\Duplicati.Library.Backend.GoogleServices.csproj", "{5489181D-950C-44AF-873C-45EB0A3B6BD2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.OpenStack", "Duplicati\Library\Backend\OpenStack\Duplicati.Library.Backend.OpenStack.csproj", "{D9E4E686-423C-48EC-A392-404E7C00860C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.RecoveryTool", "Duplicati\CommandLine\RecoveryTool\Duplicati.CommandLine.RecoveryTool.csproj", "{4A010589-76E6-4F05-A5C4-4598D5DF11F8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Box", "Duplicati\Library\Backend\Box\Duplicati.Library.Backend.Box.csproj", "{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AlternativeFTP", "Duplicati\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj", "{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Backblaze", "Duplicati\Library\Backend\Backblaze\Duplicati.Library.Backend.Backblaze.csproj", "{61C43D61-4368-4942-84A3-1EB623F4EF2A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Dropbox", "Duplicati\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj", "{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Mega", "Duplicati\Library\Backend\Mega\Duplicati.Library.Backend.Mega.csproj", "{6643A5AE-AB38-453F-ADCE-408E35A81A83}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.SharePoint", "Duplicati\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj", "{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Tools", "Duplicati\Tools\Duplicati.Tools.csproj", "{0797AA22-C5DD-4950-BB60-34765AB8C6DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Sia", "Duplicati\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj", "{32A74526-3E5F-413A-8CB4-1EFDAD4C8B91}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Common", "Duplicati\Library\Common\Duplicati.Library.Common.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Jottacloud", "Duplicati\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj", "{2CD5DBC3-3DA6-432D-BA97-F0B8D24501C2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Rclone", "Duplicati\Library\Backend\Rclone\Duplicati.Library.Backend.Rclone.csproj", "{851A1CB8-3CEB-41B4-956F-34D760D2A8E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Storj", "Duplicati\Library\Backend\Storj\Duplicati.Library.Backend.Storj.csproj", "{AE035E01-C917-4F13-A35E-78F21C1A2F17}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.TencentCOS", "Duplicati\Library\Backend\TencentCOS\Duplicati.Library.Backend.TencentCOS.csproj", "{545DD6D4-9476-42D6-B51C-A28E000C489E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Tardigrade", "Duplicati\Library\Backend\Tardigrade\Duplicati.Library.Backend.Tardigrade.csproj", "{9A04CB37-DA72-4008-9703-3AC5191974E9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Idrivee2", "Duplicati\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj", "{6B594D23-B629-465C-B799-70EE9E56C218}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.Build.0 = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.Build.0 = Release|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.Build.0 = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.Build.0 = Release|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Release|Any CPU.Build.0 = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.Build.0 = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.Build.0 = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.Build.0 = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.Build.0 = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.Build.0 = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.Build.0 = Release|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|Any CPU.Build.0 = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.Build.0 = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.Build.0 = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.Build.0 = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.Build.0 = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.Build.0 = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.Build.0 = Release|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Release|Any CPU.Build.0 = Release|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Release|Any CPU.Build.0 = Release|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Release|Any CPU.Build.0 = Release|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Release|Any CPU.Build.0 = Release|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Release|Any CPU.Build.0 = Release|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Release|Any CPU.Build.0 = Release|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Release|Any CPU.Build.0 = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.Build.0 = Release|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Release|Any CPU.Build.0 = Release|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Release|Any CPU.Build.0 = Release|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Release|Any CPU.Build.0 = Release|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Release|Any CPU.Build.0 = Release|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Release|Any CPU.Build.0 = Release|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Release|Any CPU.Build.0 = Release|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Release|Any CPU.Build.0 = Release|Any CPU
{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}.Release|Any CPU.Build.0 = Release|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Release|Any CPU.Build.0 = Release|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Release|Any CPU.Build.0 = Release|Any CPU
{0797AA22-C5DD-4950-BB60-34765AB8C6DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0797AA22-C5DD-4950-BB60-34765AB8C6DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0797AA22-C5DD-4950-BB60-34765AB8C6DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0797AA22-C5DD-4950-BB60-34765AB8C6DD}.Release|Any CPU.Build.0 = Release|Any CPU
{32A74526-3E5F-413A-8CB4-1EFDAD4C8B91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32A74526-3E5F-413A-8CB4-1EFDAD4C8B91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32A74526-3E5F-413A-8CB4-1EFDAD4C8B91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32A74526-3E5F-413A-8CB4-1EFDAD4C8B91}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Release|Any CPU.Build.0 = Release|Any CPU
{2CD5DBC3-3DA6-432D-BA97-F0B8D24501C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2CD5DBC3-3DA6-432D-BA97-F0B8D24501C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CD5DBC3-3DA6-432D-BA97-F0B8D24501C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CD5DBC3-3DA6-432D-BA97-F0B8D24501C2}.Release|Any CPU.Build.0 = Release|Any CPU
{851A1CB8-3CEB-41B4-956F-34D760D2A8E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{851A1CB8-3CEB-41B4-956F-34D760D2A8E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{851A1CB8-3CEB-41B4-956F-34D760D2A8E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{851A1CB8-3CEB-41B4-956F-34D760D2A8E5}.Release|Any CPU.Build.0 = Release|Any CPU
{C16639F6-DACC-4DD9-86CD-8B937516B340}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C16639F6-DACC-4DD9-86CD-8B937516B340}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C16639F6-DACC-4DD9-86CD-8B937516B340}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C16639F6-DACC-4DD9-86CD-8B937516B340}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3221EB9F-EE08-460E-B236-CD594688FC5F}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Duplicati\CommandLine\Duplicati.CommandLine.csproj
Policies = $0
$0.StandardHeader = $1
$1.Text = @ Copyright (C) ${Year}, The Duplicati Team\nhttps://duplicati.com, hello@duplicati.com\n\nPermission is hereby granted, free of charge, to any person obtaining a \ncopy of this software and associated documentation files (the "Software"), \nto deal in the Software without restriction, including without limitation \nthe rights to use, copy, modify, merge, publish, distribute, sublicense, \nand/or sell copies of the Software, and to permit persons to whom the \nSoftware is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in \nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS \nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE \nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING \nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER \nDEALINGS IN THE SOFTWARE.\n
$1.IncludeInNewFiles = True
$0.DotNetNamingPolicy = $2
$2.DirectoryNamespaceAssociation = PrefixedHierarchical
$2.ResourceNamePolicy = FileFormatDefault
$0.TextStylePolicy = $5
$3.inheritsSet = VisualStudio
$3.scope = text/plain
$3.FileWidth = 120
$3.EolMarker = Windows
$3.inheritsScope = text/plain
$0.CSharpFormattingPolicy = $4
$4.IndentSwitchBody = True
$4.AnonymousMethodBraceStyle = NextLine
$4.PropertyBraceStyle = NextLine
$4.PropertyGetBraceStyle = NextLine
$4.PropertySetBraceStyle = NextLine
$4.EventBraceStyle = NextLine
$4.EventAddBraceStyle = NextLine
$4.EventRemoveBraceStyle = NextLine
$4.StatementBraceStyle = NextLine
$4.ElseNewLinePlacement = NewLine
$4.ElseIfNewLinePlacement = SameLine
$4.CatchNewLinePlacement = NewLine
$4.FinallyNewLinePlacement = NewLine
$4.BeforeMethodDeclarationParentheses = False
$4.BeforeMethodCallParentheses = False
$4.BeforeConstructorDeclarationParentheses = False
$4.BeforeIndexerDeclarationBracket = False
$4.BeforeDelegateDeclarationParentheses = False
$4.NewParentheses = False
$4.ForParentheses = False
$4.ForeachParentheses = False
$4.LockParentheses = False
$4.UsingParentheses = False
$4.SpacesBeforeBrackets = False
$4.inheritsSet = Mono
$4.inheritsScope = text/x-csharp
$4.scope = text/x-csharp
$5.FileWidth = 120
$5.EolMarker = Windows
$5.inheritsSet = VisualStudio
$5.inheritsScope = text/plain
$5.scope = text/plain
EndGlobalSection
GlobalSection(SubversionScc) = preSolution
Svn-Managed = True
Manager = AnkhSVN - Subversion Support for Visual Studio
EndGlobalSection
EndGlobal
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using Duplicati.Library.Utility;
using Duplicati.Server;
using Duplicati.Server.Serialization.Interface;
namespace Duplicati.WebserverCore.Abstractions;
public interface IScheduler
{
/// <summary>
/// Initializes scheduler
/// </summary>
/// <param name="worker">The worker thread</param>
void Init(WorkerThread<Runner.IRunnerData> worker);
IList<Tuple<long, string>> GetSchedulerQueueIds();
/// <summary>
/// Terminates the thread. Any items still in queue will be removed
/// </summary>
/// <param name="wait">True if the call should block until the thread has exited, false otherwise</param>
void Terminate(bool wait);
/// <summary>
/// Subscribes to the event that is triggered when the schedule changes
/// </summary>
void SubScribeToNewSchedule(Action handler);
/// <summary>
/// A snapshot copy of the current schedule list
/// </summary>
List<KeyValuePair<DateTime, ISchedule>> Schedule { get; }
/// <summary>
/// A snapshot copy of the current worker queue, that is items that are scheduled, but waiting for execution
/// </summary>
List<Runner.IRunnerData> WorkerQueue { get; }
/// <summary>
/// Forces the scheduler to re-evaluate the order.
/// Call this method if something changes
/// </summary>
void Reschedule();
}
@@ -0,0 +1,17 @@
#nullable enable
using System;
using Duplicati.Library.Utility;
using Duplicati.Server;
namespace Duplicati.Library.RestAPI.Abstractions;
public interface IWorkerThreadsManager
{
void Spawn(Action<Runner.IRunnerData> item);
Tuple<long, string>? CurrentTask { get; }
WorkerThread<Runner.IRunnerData>? WorkerThread { get; }
void UpdateThrottleSpeeds();
long AddTask(Runner.IRunnerData data, bool skipQueue = false);
}
@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Duplicati.Server.Database;
using Duplicati.Server.Serialization;
using Duplicati.Server.Serialization.Interface;
namespace Duplicati.Library.RestAPI;
public static class BackupImportExportHandler
{
public static void RemovePasswords(IBackup backup)
{
backup.SanitizeSettings();
backup.SanitizeTargetUrl();
}
public static byte[] ExportToJSON(Connection connection, IBackup backup, string passphrase)
{
Server.Serializable.ImportExportStructure ipx = connection.PrepareBackupForExport(backup);
byte[] data;
using (var ms = new System.IO.MemoryStream())
{
using (var sw = new System.IO.StreamWriter(ms))
{
Serializer.SerializeJson(sw, ipx, true);
if (!string.IsNullOrWhiteSpace(passphrase))
{
ms.Position = 0;
using (var ms2 = new System.IO.MemoryStream())
{
using (var m = new Duplicati.Library.Encryption.AESEncryption(passphrase, new Dictionary<string, string>()))
{
m.Encrypt(ms, ms2);
data = ms2.ToArray();
}
}
}
else
{
data = ms.ToArray();
}
}
}
return data;
}
public static Server.Serializable.ImportExportStructure ImportBackup(string configurationFile, bool importMetadata, Func<string> getPassword, Dictionary<string, string> advancedOptions)
{
// This removes the ID and DBPath from the backup configuration.
Server.Serializable.ImportExportStructure importedStructure = LoadConfiguration(configurationFile, importMetadata, getPassword);
// This will create the Duplicati-server.sqlite database file if it doesn't exist.
using (Duplicati.Server.Database.Connection connection = FIXMEGlobal.GetDatabaseConnection(advancedOptions))
{
if (connection.Backups.Any(x => x.Name.Equals(importedStructure.Backup.Name, StringComparison.OrdinalIgnoreCase)))
{
throw new InvalidOperationException($"A backup with the name {importedStructure.Backup.Name} already exists.");
}
string error = connection.ValidateBackup(importedStructure.Backup, importedStructure.Schedule);
if (!string.IsNullOrWhiteSpace(error))
{
throw new InvalidOperationException(error);
}
// This creates a new ID and DBPath.
connection.AddOrUpdateBackupAndSchedule(importedStructure.Backup, importedStructure.Schedule);
}
return importedStructure;
}
public static Server.Serializable.ImportExportStructure LoadConfiguration(string filename, bool importMetadata, Func<string> getPassword)
{
Server.Serializable.ImportExportStructure ipx;
var buf = new byte[3];
using (var fs = System.IO.File.OpenRead(filename))
{
Duplicati.Library.Utility.Utility.ForceStreamRead(fs, buf, buf.Length);
fs.Position = 0;
if (buf[0] == 'A' && buf[1] == 'E' && buf[2] == 'S')
{
using (var m = new Duplicati.Library.Encryption.AESEncryption(getPassword(), new Dictionary<string, string>()))
{
using (var m2 = m.Decrypt(fs))
{
using (var sr = new System.IO.StreamReader(m2))
{
ipx = Serializer.Deserialize<Server.Serializable.ImportExportStructure>(sr);
}
}
}
}
else
{
using (var sr = new System.IO.StreamReader(fs))
{
ipx = Serializer.Deserialize<Server.Serializable.ImportExportStructure>(sr);
}
}
}
if (ipx.Backup == null)
{
throw new Exception("No backup found in document");
}
if (ipx.Backup.Metadata == null)
{
ipx.Backup.Metadata = new Dictionary<string, string>();
}
if (!importMetadata)
{
ipx.Backup.Metadata.Clear();
}
ipx.Backup.ID = null;
ipx.Backup.DBPath = null;
if (ipx.Schedule != null)
{
ipx.Schedule.ID = -1;
}
return ipx;
}
}
@@ -50,7 +50,7 @@ namespace Duplicati.Server.Database
{
this.ID = null;
}
internal void LoadChildren(Connection con)
{
if (this.IsTemporary)
@@ -69,7 +69,9 @@ namespace Duplicati.Server.Database
this.Metadata = con.GetMetadata(id);
}
}
protected void SetDBPath(string path) => this.DBPath = path;
/// <summary>
/// The backup ID
/// </summary>
@@ -94,27 +96,27 @@ namespace Duplicati.Server.Database
/// The path to the local database
/// </summary>
public string DBPath { get; internal set; }
/// <summary>
/// The backup source folders and files
/// </summary>
public string[] Sources { get; set; }
/// <summary>
/// The backup settings
/// </summary>
public ISetting[] Settings { get; set; }
/// <summary>
/// The filters applied to the source files
/// </summary>
public IFilter[] Filters { get; set; }
/// <summary>
/// The backup metadata
/// </summary>
public IDictionary<string, string> Metadata { get; set; }
public IDictionary<string, string> Metadata { get; set; }
/// <summary>
/// Gets a value indicating if this instance is not persisted to the database
/// </summary>
@@ -1,14 +1,14 @@
/*
Notifications not yet acknowledged by the user
*/
CREATE TABLE "Notification" (
"ID" INTEGER PRIMARY KEY,
"Type" TEXT NOT NULL,
"Title" TEXT NOT NULL,
"Message" TEXT NOT NULL,
"Exception" TEXT NOT NULL,
"BackupID" TEXT NULL,
"Action" TEXT NOT NULL,
"Timestamp" INTEGER NOT NULL
);
/*
Notifications not yet acknowledged by the user
*/
CREATE TABLE "Notification" (
"ID" INTEGER PRIMARY KEY,
"Type" TEXT NOT NULL,
"Title" TEXT NOT NULL,
"Message" TEXT NOT NULL,
"Exception" TEXT NOT NULL,
"BackupID" TEXT NULL,
"Action" TEXT NOT NULL,
"Timestamp" INTEGER NOT NULL
);
@@ -1,9 +1,9 @@
/*
Key/value storage for frontends
*/
CREATE TABLE "UIStorage" (
"Scheme" TEXT NOT NULL,
"Key" TEXT NOT NULL,
"Value" TEXT NOT NULL
);
/*
Key/value storage for frontends
*/
CREATE TABLE "UIStorage" (
"Scheme" TEXT NOT NULL,
"Key" TEXT NOT NULL,
"Value" TEXT NOT NULL
);
@@ -1,11 +1,11 @@
/*
Long-term temporary file records
*/
CREATE TABLE "TempFile" (
"ID" INTEGER PRIMARY KEY,
"Origin" TEXT NOT NULL,
"Path" TEXT NOT NULL,
"Timestamp" INTEGER NOT NULL,
"Expires" INTEGER NOT NULL
);
/*
Long-term temporary file records
*/
CREATE TABLE "TempFile" (
"ID" INTEGER PRIMARY KEY,
"Origin" TEXT NOT NULL,
"Path" TEXT NOT NULL,
"Timestamp" INTEGER NOT NULL,
"Expires" INTEGER NOT NULL
);
@@ -0,0 +1,9 @@
/*
Token Family table
*/
CREATE TABLE "TokenFamily" (
"ID" TEXT PRIMARY KEY,
"UserId" TEXT NOT NULL,
"Counter" INTEGER NOT NULL,
"LastUpdated" INTEGER NOT NULL
);
@@ -1,158 +1,168 @@
/*
* The primary table that stores all backups.
*
* The name and tag are free form user strings.
* The tags are comma separated
* the TargetURL is the url to remote storage,
* and the DBPath is the path to the local database
*/
CREATE TABLE "Backup" (
"ID" INTEGER PRIMARY KEY AUTOINCREMENT,
"Name" TEXT NOT NULL,
"Description" TEXT NOT NULL DEFAULT '',
"Tags" TEXT NOT NULL,
"TargetURL" TEXT NOT NULL,
"DBPath" TEXT NOT NULL
);
/*
* The table that stores all schedules
*
* Tags is a comma separated parsed field that indicates
* which backups to run when activated.
* special tags are ID:1 which means backup with ID = 1
*
* Time is the scheduled time, and lastRun is the last time the backup was executed
*
* Rule is a special parsed field
*/
CREATE TABLE "Schedule" (
"ID" INTEGER PRIMARY KEY,
"Tags" TEXT NOT NULL,
"Time" INTEGER NOT NULL,
"Repeat" TEXT NOT NULL,
"LastRun" INTEGER NOT NULL,
"Rule" TEXT NOT NULL
);
/*
* The source table is a list of source folders and files
*/
CREATE TABLE "Source" (
"BackupID" INTEGER NOT NULL,
"Path" TEXT NOT NULL
);
/*
* The filter table contains all filters associated with a backup.
* The special backupID -1 means "applied to all backups"
* The expression is the filter, if the filter is a regular
* expression, it is surrounded by hard brackets [ ]
*/
CREATE TABLE "Filter" (
"BackupID" INTEGER NOT NULL,
"Order" INTEGER NOT NULL,
"Include" INTEGER NOT NULL,
"Expression" TEXT NOT NULL
);
/*
* All options are stored in this table
*
* The special backupID -1 means "applied to all backups".
*
* The filter is used to indicate what the option applies to,
* for instance backend:s3 will only apply to backends of type S3
*
* The name and value are the option name and value
*/
CREATE TABLE "Option" (
"BackupID" INTEGER NOT NULL,
"Filter" TEXT NOT NULL,
"Name" TEXT NOT NULL,
"Value" TEXT NOT NULL
);
/*
* Recorded metadata about a backup
* This table contains metadata, such as when the backup was last started,
* how long it took, how many files there were, how big the backup set was,
* how much data was uploaded, downloaded, how fast, how much space is left,
* and similar data. Programs can use this information to improve the display,
* but cannot count on these values being present
*/
CREATE TABLE "Metadata" (
"BackupID" INTEGER NOT NULL,
"Name" TEXT NOT NULL,
"Value" TEXT NOT NULL
);
/*
* The log of operations initiated by the scheduler/user
*/
CREATE TABLE "Log" (
"BackupID" INTEGER NOT NULL,
"Description" TEXT NOT NULL,
"Start" INTEGER NOT NULL,
"Finish" INTEGER NOT NULL,
"Result" TEXT NOT NULL,
"SuggestedIcon" TEXT NOT NULL
);
/*
* The log of errors
*/
CREATE TABLE "ErrorLog" (
"BackupID" INTEGER,
"Message" TEXT NOT NULL,
"Exception" TEXT,
"Timestamp" INTEGER NOT NULL
);
/*
Internal version tracking
*/
CREATE TABLE "Version" (
"ID" INTEGER PRIMARY KEY,
"Version" INTEGER NOT NULL
);
/*
Notifications not yet acknowledged by the user
*/
CREATE TABLE "Notification" (
"ID" INTEGER PRIMARY KEY,
"Type" TEXT NOT NULL,
"Title" TEXT NOT NULL,
"Message" TEXT NOT NULL,
"Exception" TEXT NOT NULL,
"BackupID" TEXT NULL,
"Action" TEXT NOT NULL,
"Timestamp" INTEGER NOT NULL,
"LogEntryID" TEXT NULL,
"MessageID" TEXT NULL,
"MessageLogTag" TEXT NULL
);
/*
Key/value storage for frontends
*/
CREATE TABLE "UIStorage" (
"Scheme" TEXT NOT NULL,
"Key" TEXT NOT NULL,
"Value" TEXT NOT NULL
);
/*
Long-term temporary file records
*/
CREATE TABLE "TempFile" (
"ID" INTEGER PRIMARY KEY,
"Origin" TEXT NOT NULL,
"Path" TEXT NOT NULL,
"Timestamp" INTEGER NOT NULL,
"Expires" INTEGER NOT NULL
);
INSERT INTO "Version" ("Version") VALUES (6);
/*
* The primary table that stores all backups.
*
* The name and tag are free form user strings.
* The tags are comma separated
* the TargetURL is the url to remote storage,
* and the DBPath is the path to the local database
*/
CREATE TABLE "Backup" (
"ID" INTEGER PRIMARY KEY AUTOINCREMENT,
"Name" TEXT NOT NULL,
"Description" TEXT NOT NULL DEFAULT '',
"Tags" TEXT NOT NULL,
"TargetURL" TEXT NOT NULL,
"DBPath" TEXT NOT NULL
);
/*
* The table that stores all schedules
*
* Tags is a comma separated parsed field that indicates
* which backups to run when activated.
* special tags are ID:1 which means backup with ID = 1
*
* Time is the scheduled time, and lastRun is the last time the backup was executed
*
* Rule is a special parsed field
*/
CREATE TABLE "Schedule" (
"ID" INTEGER PRIMARY KEY,
"Tags" TEXT NOT NULL,
"Time" INTEGER NOT NULL,
"Repeat" TEXT NOT NULL,
"LastRun" INTEGER NOT NULL,
"Rule" TEXT NOT NULL
);
/*
* The source table is a list of source folders and files
*/
CREATE TABLE "Source" (
"BackupID" INTEGER NOT NULL,
"Path" TEXT NOT NULL
);
/*
* The filter table contains all filters associated with a backup.
* The special backupID -1 means "applied to all backups"
* The expression is the filter, if the filter is a regular
* expression, it is surrounded by hard brackets [ ]
*/
CREATE TABLE "Filter" (
"BackupID" INTEGER NOT NULL,
"Order" INTEGER NOT NULL,
"Include" INTEGER NOT NULL,
"Expression" TEXT NOT NULL
);
/*
* All options are stored in this table
*
* The special backupID -1 means "applied to all backups".
*
* The filter is used to indicate what the option applies to,
* for instance backend:s3 will only apply to backends of type S3
*
* The name and value are the option name and value
*/
CREATE TABLE "Option" (
"BackupID" INTEGER NOT NULL,
"Filter" TEXT NOT NULL,
"Name" TEXT NOT NULL,
"Value" TEXT NOT NULL
);
/*
* Recorded metadata about a backup
* This table contains metadata, such as when the backup was last started,
* how long it took, how many files there were, how big the backup set was,
* how much data was uploaded, downloaded, how fast, how much space is left,
* and similar data. Programs can use this information to improve the display,
* but cannot count on these values being present
*/
CREATE TABLE "Metadata" (
"BackupID" INTEGER NOT NULL,
"Name" TEXT NOT NULL,
"Value" TEXT NOT NULL
);
/*
* The log of operations initiated by the scheduler/user
*/
CREATE TABLE "Log" (
"BackupID" INTEGER NOT NULL,
"Description" TEXT NOT NULL,
"Start" INTEGER NOT NULL,
"Finish" INTEGER NOT NULL,
"Result" TEXT NOT NULL,
"SuggestedIcon" TEXT NOT NULL
);
/*
* The log of errors
*/
CREATE TABLE "ErrorLog" (
"BackupID" INTEGER,
"Message" TEXT NOT NULL,
"Exception" TEXT,
"Timestamp" INTEGER NOT NULL
);
/*
Internal version tracking
*/
CREATE TABLE "Version" (
"ID" INTEGER PRIMARY KEY,
"Version" INTEGER NOT NULL
);
/*
Notifications not yet acknowledged by the user
*/
CREATE TABLE "Notification" (
"ID" INTEGER PRIMARY KEY,
"Type" TEXT NOT NULL,
"Title" TEXT NOT NULL,
"Message" TEXT NOT NULL,
"Exception" TEXT NOT NULL,
"BackupID" TEXT NULL,
"Action" TEXT NOT NULL,
"Timestamp" INTEGER NOT NULL,
"LogEntryID" TEXT NULL,
"MessageID" TEXT NULL,
"MessageLogTag" TEXT NULL
);
/*
Key/value storage for frontends
*/
CREATE TABLE "UIStorage" (
"Scheme" TEXT NOT NULL,
"Key" TEXT NOT NULL,
"Value" TEXT NOT NULL
);
/*
Long-term temporary file records
*/
CREATE TABLE "TempFile" (
"ID" INTEGER PRIMARY KEY,
"Origin" TEXT NOT NULL,
"Path" TEXT NOT NULL,
"Timestamp" INTEGER NOT NULL,
"Expires" INTEGER NOT NULL
);
/*
Token Family table
*/
CREATE TABLE "TokenFamily" (
"ID" TEXT PRIMARY KEY,
"UserId" TEXT NOT NULL,
"Counter" INTEGER NOT NULL,
"LastUpdated" INTEGER NOT NULL
);
INSERT INTO "Version" ("Version") VALUES (7);
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Duplicati.Library.RestAPI.Database
{
public static class DatabaseConnectionSchemaMarker
{
}
}
@@ -1,4 +1,4 @@
// Copyright (C) 2024, The Duplicati Team
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -33,7 +33,7 @@ namespace Duplicati.Server.Database
public string Exception { get; set; }
public string BackupID { get; set; }
public string Action { get; set; }
public DateTime Timestamp { get; set; }
public DateTime Timestamp { get; set; }
public string LogEntryID { get; set; }
public string MessageID { get; set; }
public string MessageLogTag { get; set; }
@@ -33,38 +33,38 @@ namespace Duplicati.Server.Database
public string Repeat { get; set; }
public DateTime LastRun { get; set; }
public string Rule { get; set; }
public DayOfWeek[] AllowedDays
{
{
get
{
if (string.IsNullOrEmpty(this.Rule))
return null;
var days = (from n in this.Rule.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
where n.StartsWith("AllowedWeekDays=", StringComparison.OrdinalIgnoreCase)
select n.Substring("AllowedWeekDays=".Length).Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries))
var days = (from n in this.Rule.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
where n.StartsWith("AllowedWeekDays=", StringComparison.OrdinalIgnoreCase)
select n.Substring("AllowedWeekDays=".Length).Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
.FirstOrDefault();
if (days == null)
return null;
return (from n in days
return (from n in days
where Enum.TryParse<DayOfWeek>(n, true, out _)
select (DayOfWeek)Enum.Parse(typeof(DayOfWeek), n, true))
.ToArray();
}
set
{
var parts =
string.IsNullOrEmpty(this.Rule) ?
var parts =
string.IsNullOrEmpty(this.Rule) ?
new string[0] :
(from n in this.Rule.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
where !n.StartsWith("AllowedWeekDays=", StringComparison.OrdinalIgnoreCase)
select n);
(from n in this.Rule.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
where !n.StartsWith("AllowedWeekDays=", StringComparison.OrdinalIgnoreCase)
select n);
if (value != null && value.Length != 0)
parts = parts.Union(new string[] {
"AllowedWeekDays=" +
@@ -74,7 +74,7 @@ namespace Duplicati.Server.Database
select Enum.GetName(typeof(DayOfWeek), n)).Distinct()
)
}).Distinct();
this.Rule = string.Join(";", parts);
}
}
@@ -1,4 +1,4 @@
// Copyright (C) 2024, The Duplicati Team
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Copyright>Copyright © 2024 Team Duplicati, MIT license</Copyright>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Database\Database schema\**" />
<Compile Remove="Database\Database schema\DatabaseConnectionSchemaMarker.cs" />
<EmbeddedResource Include="Database\DatabaseConnectionSchemaMarker.cs" />
<EmbeddedResource Include="newbackup.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Win32.SystemEvents" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Duplicati\CommandLine\CLI\Duplicati.CommandLine.csproj" />
<ProjectReference Include="..\Duplicati\Library\Common\Duplicati.Library.Common.csproj" />
<ProjectReference Include="..\Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj" />
<ProjectReference Include="..\Duplicati\Library\Main\Duplicati.Library.Main.csproj" />
<ProjectReference Include="..\Duplicati\Library\Snapshots\Duplicati.Library.Snapshots.csproj" />
<ProjectReference Include="..\Duplicati\Library\SQLiteHelper\Duplicati.Library.SQLiteHelper.csproj" />
<ProjectReference Include="..\Duplicati\Server\Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="WebServer\Kestrel\" />
</ItemGroup>
</Project>
@@ -1,97 +1,75 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Duplicati.Server
{
/// <summary>
/// This class handles synchronized waiting for events
/// </summary>
public class EventPollNotify
{
/// <summary>
/// The lock that grants exclusive access to control structures
/// </summary>
private readonly object m_lock = new object();
/// <summary>
/// The current eventID
/// </summary>
private long m_eventNo = 0;
/// <summary>
/// The list of subscribed waiting threads
/// </summary>
private readonly Queue<System.Threading.ManualResetEvent> m_waitQueue = new Queue<System.Threading.ManualResetEvent>();
/// <summary>
/// An eventhandler for subscribing to event updates without blocking
/// </summary>
public event EventHandler NewEvent;
/// <summary>
/// Gets the current event ID
/// </summary>
public long EventNo { get { return m_eventNo; } }
/// <summary>
/// Call to wait for an event that is newer than the current known event
/// </summary>
/// <param name="eventId">The last known event id</param>
/// <param name="milliseconds">The number of milliseconds to block</param>
/// <returns>The current event id</returns>
public long Wait(long eventId, int milliseconds)
{
System.Threading.ManualResetEvent mre;
lock (m_lock)
{
//If a newer event has already occured, return immediately
if (eventId != m_eventNo)
return m_eventNo;
//Otherwise register this thread as waiting
mre = new System.Threading.ManualResetEvent(false);
m_waitQueue.Enqueue(mre);
}
//Wait until we are signalled or the time has elapsed
mre.WaitOne(milliseconds, false);
return m_eventNo;
}
/// <summary>
/// Signals that an event has occurred and notifies all waiting threads
/// </summary>
public void SignalNewEvent()
{
lock (m_lock)
{
m_eventNo++;
while (m_waitQueue.Count > 0)
m_waitQueue.Dequeue().Set();
}
if (NewEvent != null)
NewEvent(this, null);
}
}
}
using System;
using System.Collections.Generic;
namespace Duplicati.Server
{
/// <summary>
/// This class handles synchronized waiting for events
/// </summary>
public class EventPollNotify
{
/// <summary>
/// The lock that grants exclusive access to control structures
/// </summary>
private readonly object m_lock = new object();
/// <summary>
/// The current eventID
/// </summary>
private long m_eventNo = 0;
/// <summary>
/// The list of subscribed waiting threads
/// </summary>
private readonly Queue<System.Threading.ManualResetEvent> m_waitQueue = new Queue<System.Threading.ManualResetEvent>();
/// <summary>
/// An eventhandler for subscribing to event updates without blocking
/// </summary>
public event EventHandler NewEvent;
/// <summary>
/// Gets the current event ID
/// </summary>
public long EventNo { get { return m_eventNo; } }
/// <summary>
/// Call to wait for an event that is newer than the current known event
/// </summary>
/// <param name="eventId">The last known event id</param>
/// <param name="milliseconds">The number of milliseconds to block</param>
/// <returns>The current event id</returns>
public long Wait(long eventId, int milliseconds)
{
System.Threading.ManualResetEvent mre;
lock (m_lock)
{
//If a newer event has already occured, return immediately
if (eventId != m_eventNo)
return m_eventNo;
//Otherwise register this thread as waiting
mre = new System.Threading.ManualResetEvent(false);
m_waitQueue.Enqueue(mre);
}
//Wait until we are signalled or the time has elapsed
mre.WaitOne(milliseconds, false);
return m_eventNo;
}
/// <summary>
/// Signals that an event has occurred and notifies all waiting threads
/// </summary>
public void SignalNewEvent()
{
lock (m_lock)
{
m_eventNo++;
while (m_waitQueue.Count > 0)
m_waitQueue.Dequeue().Set();
}
if (NewEvent != null)
NewEvent(this, null);
}
}
}
+107
View File
@@ -0,0 +1,107 @@
using Duplicati.Server;
using System;
using System.Collections.Generic;
using Duplicati.Library.RestAPI.Abstractions;
using Duplicati.Library.Utility;
using Duplicati.WebserverCore.Abstractions;
using Microsoft.Extensions.DependencyInjection;
namespace Duplicati.Library.RestAPI
{
/**
* In the absense of dependancy injection, there is a significant amount of variables exposed through Program as globals.
* This causes a problem decoupling classes and leads to circular dependancies.
*/
public static class FIXMEGlobal
{
/// <summary>
/// The placeholder for passwords in the UI
/// </summary>
public const string PASSWORD_PLACEHOLDER = "**********";
public static IServiceProvider Provider { get; set; }
/// <summary>
/// This is the only access to the database
/// </summary>
public static Server.Database.Connection DataConnection;
/// <summary>
/// A delegate method for creating a copy of the current progress state
/// </summary>
public static Func<Duplicati.Server.Serialization.Interface.IProgressEventData> GenerateProgressState;
/// <summary>
/// The status event signaler, used to control long polling of status updates
/// </summary>
public static EventPollNotify StatusEventNotifyer => Provider.GetRequiredService<EventPollNotify>();
/// <summary>
/// For keeping and incrementing last last events Ids of db save and last notification
/// </summary>
public static INotificationUpdateService NotificationUpdateService => Provider.GetRequiredService<INotificationUpdateService>();
/// <summary>
/// Checks if the server has started and is listening for events
/// </summary>
public static bool IsServerStarted => Provider != null;
/// <summary>
/// This is the working thread
/// </summary>
public static WorkerThread<Runner.IRunnerData> WorkThread =>
Provider.GetRequiredService<IWorkerThreadsManager>().WorkerThread;
public static IWorkerThreadsManager WorkerThreadsManager =>
Provider.GetRequiredService<IWorkerThreadsManager>();
public static Action StartOrStopUsageReporter;
/// <summary>
/// Gets the folder where Duplicati data is stored
/// </summary>
public static string DataFolder;
/// <summary>
/// This is the scheduling thread
/// </summary>
public static IScheduler Scheduler => Provider.GetRequiredService<IScheduler>();
/// <summary>
/// The log redirect handler
/// </summary>
public static readonly LogWriteHandler LogHandler = new LogWriteHandler();
public static Func<Dictionary<string, string>, Server.Database.Connection> GetDatabaseConnection;
/// <summary>
/// The update poll thread.
/// </summary>
public static UpdatePollThread UpdatePoller => Provider.GetRequiredService<UpdatePollThread>();
/// <summary>
/// Used to check the origin of the web server (e.g. Tray icon or a stand alone Server)
/// </summary>
public static string Origin = "Server";
/// <summary>
/// The application exit event
/// </summary>
public static System.Threading.ManualResetEvent ApplicationExitEvent;
/// <summary>
/// List of completed task results
/// </summary>
public static readonly List<KeyValuePair<long, Exception>> TaskResultCache = new List<KeyValuePair<long, Exception>>();
/// <summary>
/// This is the lock to be used before manipulating the shared resources
/// </summary>
public static readonly object MainLock = new object();
}
}
@@ -1,4 +1,4 @@
// Copyright (C) 2024, The Duplicati Team
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,388 +18,408 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Text;
using Duplicati.Library.Common;
namespace Duplicati.Server
{
/// <summary>
/// This class keeps track of the users modifications regarding
/// throttling and pause/resume
/// </summary>
public class LiveControls
{
/// <summary>
/// The tag used for logging
/// </summary>
private static readonly string LOGTAG = Duplicati.Library.Logging.Log.LogTagFromType<LiveControls>();
/// <summary>
/// An event that is activated when the pause state changes
/// </summary>
public event EventHandler StateChanged;
/// <summary>
/// An event that is activated when the thread priority changes
/// </summary>
public event EventHandler ThreadPriorityChanged;
/// <summary>
/// An event that is activated when the throttle speed changes
/// </summary>
public event EventHandler ThrottleSpeedChanged;
/// <summary>
/// The possible states for the live control
/// </summary>
public enum LiveControlState
{
/// <summary>
/// Indicates that the backups are running
/// </summary>
Running,
/// <summary>
/// Indicates that the backups are currently suspended
/// </summary>
Paused
}
/// <summary>
/// The current control state
/// </summary>
private LiveControlState m_state;
/// <summary>
/// A value that indicates if the current pause state is caused by being suspended
/// </summary>
private bool m_pausedForSuspend = false;
/// <summary>
/// The time to pause for, used to ensure that a user set pause can override the suspend pause
/// </summary>
private DateTime m_suspendMinimumPause = new DateTime(0);
/// <summary>
/// Gets the current state for the control
/// </summary>
public LiveControlState State { get { return m_state; } }
/// <summary>
/// The internal variable that tracks the the priority
/// </summary>
private System.Threading.ThreadPriority? m_priority;
/// <summary>
/// The internal variable that tracks the upload limit
/// </summary>
private long? m_uploadLimit;
/// <summary>
/// The internal variable that tracks the download limit
/// </summary>
private long? m_downloadLimit;
/// <summary>
/// The object that ensures concurrent operations
/// </summary>
private readonly object m_lock = new object();
/// <summary>
/// Gets the current overridden thread priority
/// </summary>
public System.Threading.ThreadPriority? ThreadPriority
{
get { return m_priority; }
set
{
if (m_priority != value)
{
m_priority = value;
if (ThreadPriorityChanged != null)
ThreadPriorityChanged(this, null);
}
}
}
/// <summary>
/// Gets the current upload limit in bps
/// </summary>
public long? UploadLimit
{
get { return m_uploadLimit; }
set
{
if (m_uploadLimit != value)
{
m_uploadLimit = value;
if (ThrottleSpeedChanged != null)
ThrottleSpeedChanged(this, null);
}
}
}
/// <summary>
/// Gets the download limit in bps
/// </summary>
public long? DownloadLimit
{
get { return m_downloadLimit; }
set
{
if (m_downloadLimit != value)
{
m_downloadLimit = value;
if (ThrottleSpeedChanged != null)
ThrottleSpeedChanged(this, null);
}
}
}
/// <summary>
/// The timer that is activated after a pause period.
/// </summary>
private readonly System.Threading.Timer m_waitTimer;
/// <summary>
/// The time that the current pause is expected to expire
/// </summary>
private DateTime m_waitTimeExpiration = new DateTime(0);
/// <summary>
/// Constructs a new instance of the LiveControl
/// </summary>
public LiveControls(Database.ServerSettings settings)
{
m_state = LiveControlState.Running;
m_waitTimer = new System.Threading.Timer(m_waitTimer_Tick, this, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
if (!string.IsNullOrEmpty(settings.StartupDelayDuration) && settings.StartupDelayDuration != "0")
{
long milliseconds = 0;
try { milliseconds = (long)Duplicati.Library.Utility.Timeparser.ParseTimeSpan(settings.StartupDelayDuration).TotalMilliseconds; }
catch {}
if (milliseconds > 0)
{
m_waitTimeExpiration = DateTime.Now.AddMilliseconds(milliseconds);
m_waitTimer.Change(milliseconds, System.Threading.Timeout.Infinite);
m_state = LiveControlState.Paused;
}
}
m_priority = settings.ThreadPriorityOverride;
if (!string.IsNullOrEmpty(settings.DownloadSpeedLimit))
try
{
m_downloadLimit = Library.Utility.Sizeparser.ParseSize(settings.DownloadSpeedLimit, "kb");
}
catch (Exception ex)
{
Library.Logging.Log.WriteErrorMessage(LOGTAG, "ParseDownloadLimitError", ex, "Failed to parse download limit: {0}", settings.DownloadSpeedLimit);
}
if (!string.IsNullOrEmpty(settings.UploadSpeedLimit))
try
{
m_uploadLimit = Library.Utility.Sizeparser.ParseSize(settings.UploadSpeedLimit, "kb");
}
catch (Exception ex)
{
Library.Logging.Log.WriteErrorMessage(LOGTAG, "ParseUploadLimitError", ex, "Failed to parse upload limit: {0}", settings.UploadSpeedLimit);
}
try
{
if (!Platform.IsClientPosix)
RegisterHibernateMonitor();
}
catch { }
}
/// <summary>
/// Event that occurs when the timeout duration is exceeded
/// </summary>
/// <param name="sender">The sender of the event</param>
private void m_waitTimer_Tick(object sender)
{
lock (m_lock)
Resume();
}
/// <summary>
/// Internal helper to reset the timeout timer
/// </summary>
/// <param name="timeout">The time to wait</param>
private void ResetTimer(string timeout)
{
lock (m_lock)
if (!string.IsNullOrEmpty(timeout))
{
long milliseconds = (long)Duplicati.Library.Utility.Timeparser.ParseTimeSpan(timeout).TotalMilliseconds;
m_waitTimeExpiration = DateTime.Now.AddMilliseconds(milliseconds);
m_waitTimer.Change(milliseconds, System.Threading.Timeout.Infinite);
}
else
{
m_waitTimeExpiration = new DateTime(0);
m_waitTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
}
}
/// <summary>
/// Internal helper to set the pause mode
/// </summary>
private void SetPauseMode()
{
lock (m_lock)
{
if (m_state == LiveControlState.Running)
{
m_state = LiveControlState.Paused;
if (StateChanged != null)
StateChanged(this, null);
}
}
}
/// <summary>
/// Pauses the backups until resumed
/// </summary>
public void Pause()
{
lock(m_lock)
{
var fireEvent = m_waitTimeExpiration.Ticks != 0 && m_state == LiveControlState.Paused && StateChanged != null;
ResetTimer(null);
if (fireEvent)
StateChanged(this, null);
else
SetPauseMode();
}
}
/// <summary>
/// Resumes a backups to the running state
/// </summary>
public void Resume()
{
lock (m_lock)
{
if (m_state == LiveControlState.Paused)
{
//Make sure that the timer is cleared
ResetTimer(null);
m_state = LiveControlState.Running;
if (StateChanged != null)
StateChanged(this, null);
}
}
}
/// <summary>
/// Suspends the backups for a given period
/// </summary>
/// <param name="timeout">The duration to wait</param>
public void Pause(string timeout)
{
Pause(Duplicati.Library.Utility.Timeparser.ParseTimeSpan(timeout));
}
/// <summary>
/// Suspends the backups for a given period
/// </summary>
/// <param name="timeout">The duration to wait</param>
public void Pause(TimeSpan timeout)
{
lock (m_lock)
{
m_waitTimeExpiration = DateTime.Now.AddMilliseconds((long)timeout.TotalMilliseconds);
m_waitTimer.Change((long)timeout.TotalMilliseconds, System.Threading.Timeout.Infinite);
//We change the time, so we issue a new event
if (m_state == LiveControlState.Paused && StateChanged != null)
StateChanged(this, null);
else
SetPauseMode();
}
}
/// <summary>
/// Gets the time the current pause is expected to end
/// </summary>
public DateTime EstimatedPauseEnd { get { return m_waitTimeExpiration; } }
/// <summary>
/// Method for calling a Win32 API
/// </summary>
private void RegisterHibernateMonitor()
{
Microsoft.Win32.SystemEvents.PowerModeChanged += new Microsoft.Win32.PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
}
/// <summary>
/// A monitor for detecting when the system hibernates or resumes
/// </summary>
/// <param name="sender">Unused sender parameter</param>
/// <param name="_e">The event information</param>
private void SystemEvents_PowerModeChanged(object sender, object _e)
{
Microsoft.Win32.PowerModeChangedEventArgs e = _e as Microsoft.Win32.PowerModeChangedEventArgs;
if (e == null)
return;
if (e.Mode == Microsoft.Win32.PowerModes.Suspend)
{
//If we are running, register as being paused due to suspending
if (this.m_state == LiveControlState.Running)
{
this.SetPauseMode();
m_pausedForSuspend = true;
m_suspendMinimumPause = new DateTime(0);
}
else
{
if (m_waitTimeExpiration.Ticks != 0)
{
m_pausedForSuspend = true;
m_suspendMinimumPause = this.EstimatedPauseEnd;
ResetTimer(null);
}
}
}
else if (e.Mode == Microsoft.Win32.PowerModes.Resume)
{
//If we have been been paused due to suspending, we un-pause now
if (m_pausedForSuspend)
{
long delayTicks = (m_suspendMinimumPause - DateTime.Now).Ticks;
var appset = Program.DataConnection.ApplicationSettings;
if (!string.IsNullOrEmpty(appset.StartupDelayDuration) && appset.StartupDelayDuration != "0")
try { delayTicks = Math.Max(delayTicks, Library.Utility.Timeparser.ParseTimeSpan(appset.StartupDelayDuration).Ticks); }
catch { }
if (delayTicks > 0)
{
this.Pause(TimeSpan.FromTicks(delayTicks));
}
else
{
this.Resume();
}
}
m_pausedForSuspend = false;
m_suspendMinimumPause = new DateTime(0);
}
}
}
}
using System;
using System.Runtime.Versioning;
using Duplicati.Library.IO;
using Duplicati.Server.Database;
namespace Duplicati.Server
{
/// <summary>
/// This class keeps track of the users modifications regarding
/// throttling and pause/resume
/// </summary>
public class LiveControls : ILiveControls
{
/// <summary>
/// The tag used for logging
/// </summary>
private static readonly string LOGTAG = Duplicati.Library.Logging.Log.LogTagFromType<LiveControls>();
/// <summary>
/// An event that is activated when the pause state changes
/// </summary>
public event EventHandler StateChanged;
/// <summary>
/// An event that is activated when the thread priority changes
/// </summary>
public event EventHandler ThreadPriorityChanged;
/// <summary>
/// An event that is activated when the throttle speed changes
/// </summary>
public event EventHandler ThrottleSpeedChanged;
/// <summary>
/// The possible states for the live control
/// </summary>
public enum LiveControlState
{
/// <summary>
/// Indicates that the backups are running
/// </summary>
Running,
/// <summary>
/// Indicates that the backups are currently suspended
/// </summary>
Paused
}
/// <summary>
/// The current control state
/// </summary>
private LiveControlState m_state;
/// <summary>
/// A value that indicates if the current pause state is caused by being suspended
/// </summary>
private bool m_pausedForSuspend = false;
/// <summary>
/// The time to pause for, used to ensure that a user set pause can override the suspend pause
/// </summary>
private DateTime m_suspendMinimumPause = new DateTime(0);
/// <summary>
/// Gets the current state for the control
/// </summary>
public LiveControlState State { get { return m_state; } }
public bool IsPaused => State == LiveControlState.Paused;
/// <summary>
/// The internal variable that tracks the the priority
/// </summary>
private System.Threading.ThreadPriority? m_priority;
/// <summary>
/// The internal variable that tracks the upload limit
/// </summary>
private long? m_uploadLimit;
/// <summary>
/// The internal variable that tracks the download limit
/// </summary>
private long? m_downloadLimit;
/// <summary>
/// The object that ensures concurrent operations
/// </summary>
private readonly object m_lock = new object();
/// <summary>
/// Gets the current overridden thread priority
/// </summary>
public System.Threading.ThreadPriority? ThreadPriority
{
get { return m_priority; }
set
{
if (m_priority != value)
{
m_priority = value;
if (ThreadPriorityChanged != null)
ThreadPriorityChanged(this, null);
}
}
}
/// <summary>
/// Gets the current upload limit in bps
/// </summary>
public long? UploadLimit
{
get { return m_uploadLimit; }
set
{
if (m_uploadLimit != value)
{
m_uploadLimit = value;
if (ThrottleSpeedChanged != null)
ThrottleSpeedChanged(this, null);
}
}
}
/// <summary>
/// Gets the download limit in bps
/// </summary>
public long? DownloadLimit
{
get { return m_downloadLimit; }
set
{
if (m_downloadLimit != value)
{
m_downloadLimit = value;
if (ThrottleSpeedChanged != null)
ThrottleSpeedChanged(this, null);
}
}
}
/// <summary>
/// The timer that is activated after a pause period.
/// </summary>
private System.Threading.Timer m_waitTimer;
/// <summary>
/// The time that the current pause is expected to expire
/// </summary>
private DateTime m_waitTimeExpiration = new DateTime(0);
/// <summary>
/// The connection to use
/// </summary>
private readonly Connection m_connection;
/// <summary>
/// Constructs a new instance of the LiveControl
/// </summary>
/// <param name="connection">The connection to use</param>
public LiveControls(Connection connection)
{
m_connection = connection;
Init();
}
/// <summary>
/// Constructs a new instance of the LiveControl
/// </summary>
private void Init()
{
var settings = m_connection.ApplicationSettings;
m_state = LiveControlState.Running;
m_waitTimer = new System.Threading.Timer(m_waitTimer_Tick, this, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
if (!string.IsNullOrEmpty(settings.StartupDelayDuration) && settings.StartupDelayDuration != "0")
{
long milliseconds = 0;
try { milliseconds = (long)Duplicati.Library.Utility.Timeparser.ParseTimeSpan(settings.StartupDelayDuration).TotalMilliseconds; }
catch { }
if (milliseconds > 0)
{
m_waitTimeExpiration = DateTime.Now.AddMilliseconds(milliseconds);
m_waitTimer.Change(milliseconds, System.Threading.Timeout.Infinite);
m_state = LiveControlState.Paused;
}
}
m_priority = settings.ThreadPriorityOverride;
if (!string.IsNullOrEmpty(settings.DownloadSpeedLimit))
try
{
m_downloadLimit = Library.Utility.Sizeparser.ParseSize(settings.DownloadSpeedLimit, "kb");
}
catch (Exception ex)
{
Library.Logging.Log.WriteErrorMessage(LOGTAG, "ParseDownloadLimitError", ex, "Failed to parse download limit: {0}", settings.DownloadSpeedLimit);
}
if (!string.IsNullOrEmpty(settings.UploadSpeedLimit))
try
{
m_uploadLimit = Library.Utility.Sizeparser.ParseSize(settings.UploadSpeedLimit, "kb");
}
catch (Exception ex)
{
Library.Logging.Log.WriteErrorMessage(LOGTAG, "ParseUploadLimitError", ex, "Failed to parse upload limit: {0}", settings.UploadSpeedLimit);
}
try
{
if (OperatingSystem.IsWindows())
RegisterHibernateMonitor();
}
catch { }
}
/// <summary>
/// Event that occurs when the timeout duration is exceeded
/// </summary>
/// <param name="sender">The sender of the event</param>
private void m_waitTimer_Tick(object sender)
{
lock (m_lock)
Resume();
}
/// <summary>
/// Internal helper to reset the timeout timer
/// </summary>
/// <param name="timeout">The time to wait</param>
private void ResetTimer(string timeout)
{
lock (m_lock)
if (!string.IsNullOrEmpty(timeout))
{
long milliseconds = (long)Duplicati.Library.Utility.Timeparser.ParseTimeSpan(timeout).TotalMilliseconds;
m_waitTimeExpiration = DateTime.Now.AddMilliseconds(milliseconds);
m_waitTimer.Change(milliseconds, System.Threading.Timeout.Infinite);
}
else
{
m_waitTimeExpiration = new DateTime(0);
m_waitTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
}
}
/// <summary>
/// Internal helper to set the pause mode
/// </summary>
private void SetPauseMode()
{
lock (m_lock)
{
if (m_state == LiveControlState.Running)
{
m_state = LiveControlState.Paused;
if (StateChanged != null)
StateChanged(this, null);
}
}
}
/// <summary>
/// Pauses the backups until resumed
/// </summary>
public void Pause()
{
lock (m_lock)
{
var fireEvent = m_waitTimeExpiration.Ticks != 0 && m_state == LiveControlState.Paused && StateChanged != null;
ResetTimer(null);
if (fireEvent)
StateChanged(this, null);
else
SetPauseMode();
}
}
/// <summary>
/// Resumes a backups to the running state
/// </summary>
public void Resume()
{
lock (m_lock)
{
if (m_state == LiveControlState.Paused)
{
//Make sure that the timer is cleared
ResetTimer(null);
m_state = LiveControlState.Running;
if (StateChanged != null)
StateChanged(this, null);
}
}
}
/// <summary>
/// Suspends the backups for a given period
/// </summary>
/// <param name="timeout">The duration to wait</param>
public void Pause(string timeout)
{
Pause(Duplicati.Library.Utility.Timeparser.ParseTimeSpan(timeout));
}
/// <summary>
/// Suspends the backups for a given period
/// </summary>
/// <param name="timeout">The duration to wait</param>
public void Pause(TimeSpan timeout)
{
lock (m_lock)
{
m_waitTimeExpiration = DateTime.Now.AddMilliseconds((long)timeout.TotalMilliseconds);
m_waitTimer.Change((long)timeout.TotalMilliseconds, System.Threading.Timeout.Infinite);
//We change the time, so we issue a new event
if (m_state == LiveControlState.Paused && StateChanged != null)
StateChanged(this, null);
else
SetPauseMode();
}
}
/// <summary>
/// Gets the time the current pause is expected to end
/// </summary>
public DateTime EstimatedPauseEnd { get { return m_waitTimeExpiration; } }
/// <summary>
/// Method for calling a Win32 API
/// </summary>
[SupportedOSPlatform("windows")]
private void RegisterHibernateMonitor()
{
Microsoft.Win32.SystemEvents.PowerModeChanged += new Microsoft.Win32.PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
}
/// <summary>
/// A monitor for detecting when the system hibernates or resumes
/// </summary>
/// <param name="sender">Unused sender parameter</param>
/// <param name="_e">The event information</param>
[SupportedOSPlatform("windows")]
private void SystemEvents_PowerModeChanged(object sender, object _e)
{
Microsoft.Win32.PowerModeChangedEventArgs e = _e as Microsoft.Win32.PowerModeChangedEventArgs;
if (e == null)
return;
if (e.Mode == Microsoft.Win32.PowerModes.Suspend)
{
//If we are running, register as being paused due to suspending
if (this.m_state == LiveControlState.Running)
{
this.SetPauseMode();
m_pausedForSuspend = true;
m_suspendMinimumPause = new DateTime(0);
}
else
{
if (m_waitTimeExpiration.Ticks != 0)
{
m_pausedForSuspend = true;
m_suspendMinimumPause = this.EstimatedPauseEnd;
ResetTimer(null);
}
}
}
else if (e.Mode == Microsoft.Win32.PowerModes.Resume)
{
//If we have been been paused due to suspending, we un-pause now
if (m_pausedForSuspend)
{
long delayTicks = (m_suspendMinimumPause - DateTime.Now).Ticks;
var appset = m_connection.ApplicationSettings;
if (!string.IsNullOrEmpty(appset.StartupDelayDuration) && appset.StartupDelayDuration != "0")
try { delayTicks = Math.Max(delayTicks, Library.Utility.Timeparser.ParseTimeSpan(appset.StartupDelayDuration).Ticks); }
catch { }
if (delayTicks > 0)
{
this.Pause(TimeSpan.FromTicks(delayTicks));
}
else
{
this.Resume();
}
}
m_pausedForSuspend = false;
m_suspendMinimumPause = new DateTime(0);
}
}
}
}
@@ -1,4 +1,4 @@
// Copyright (C) 2024, The Duplicati Team
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -134,7 +134,7 @@ namespace Duplicati.Server
this.ExceptionID = exception.HelpID;
else
this.ExceptionID = entry.Exception.GetType().FullName;
}
}
@@ -154,15 +154,15 @@ namespace Duplicati.Server
{
m_buffer = new T[size];
if (initial != null)
foreach(var t in initial)
foreach (var t in initial)
this.Enqueue(t);
}
public int Length { get { return m_length; } }
public void Enqueue(T item)
{
lock(m_lock)
lock (m_lock)
{
m_key++;
m_buffer[m_head] = item;
@@ -178,7 +178,7 @@ namespace Duplicati.Server
public IEnumerator<T> GetEnumerator()
{
var k = m_key;
for(var i = 0; i < m_length; i++)
for (var i = 0; i < m_length; i++)
if (m_key != k)
throw new InvalidOperationException("Buffer was modified while reading");
else
@@ -194,7 +194,7 @@ namespace Duplicati.Server
public T[] FlatArray(Func<T, bool> filter = null)
{
lock(m_lock)
lock (m_lock)
if (filter == null)
return this.ToArray();
else
@@ -222,7 +222,7 @@ namespace Duplicati.Server
public void RenewTimeout(LogMessageType type)
{
lock(m_lock)
lock (m_lock)
{
m_timeouts[(int)type] = DateTime.Now.AddSeconds(30);
m_anytimeouts = true;
@@ -249,12 +249,12 @@ namespace Duplicati.Server
UpdateLogLevel();
offset = offset.ToUniversalTime();
lock(m_lock)
lock (m_lock)
{
if (m_buffer == null)
return new LogEntry[0];
return m_buffer.FlatArray((x) => x.When > offset && x.Type >= level );
return m_buffer.FlatArray((x) => x.When > offset && x.Type >= level);
}
}
@@ -263,18 +263,20 @@ namespace Duplicati.Server
RenewTimeout(level);
UpdateLogLevel();
lock(m_lock)
lock (m_lock)
{
if (m_buffer == null)
return new LogEntry[0];
var buffer = m_buffer.FlatArray((x) => x.ID > id && x.Type >= level );
var buffer = m_buffer.FlatArray((x) => x.ID > id && x.Type >= level);
// Return the <page_size> newest entries
if (buffer.Length > pagesize) {
if (buffer.Length > pagesize)
{
var index = buffer.Length - pagesize;
return buffer.Skip(index).Take(pagesize).ToArray();
}
else {
else
{
return buffer;
}
}
@@ -284,13 +286,13 @@ namespace Duplicati.Server
{
var i = 0;
return (from n in m_timeouts
let ix = i++
where n > DateTime.Now
select ix).ToArray();
let ix = i++
where n > DateTime.Now
select ix).ToArray();
}
private void UpdateLogLevel()
{
{
m_logLevel =
(LogMessageType)(GetActiveTimeouts().Union(new int[] { (int)m_serverloglevel }).Min());
}
@@ -300,9 +302,9 @@ namespace Duplicati.Server
public void WriteMessage(Duplicati.Library.Logging.LogEntry entry)
{
if (entry.Level < m_logLevel)
if (entry.Level < m_logLevel)
return;
if (m_serverfile != null && entry.Level >= m_serverloglevel)
try
{
@@ -312,7 +314,7 @@ namespace Duplicati.Server
{
}
lock(m_lock)
lock (m_lock)
{
if (m_anytimeouts)
{
@@ -0,0 +1,50 @@
namespace Duplicati.Library.RestAPI;
public interface INotificationUpdateService
{
/// <summary>
/// An event ID that increases whenever the database is updated
/// </summary>
long LastDataUpdateId { get; }
/// <summary>
/// An event ID that increases whenever a notification is updated
/// </summary>
long LastNotificationUpdateId { get; }
void IncrementLastDataUpdateId();
void IncrementLastNotificationUpdateId();
}
public class NotificationUpdateService : INotificationUpdateService
{
/// <summary>
/// An event ID that increases whenever the database is updated
/// </summary>
public long LastDataUpdateId { get; private set; } = 0;
private readonly object _lastDataUpdateIdLock = new();
/// <summary>
/// An event ID that increases whenever a notification is updated
/// </summary>
public long LastNotificationUpdateId { get; private set; } = 0;
private readonly object _lastNotificationUpdateIdLock = new();
public void IncrementLastDataUpdateId()
{
lock (_lastDataUpdateIdLock)
{
LastDataUpdateId++;
}
}
public void IncrementLastNotificationUpdateId()
{
lock (_lastNotificationUpdateIdLock)
{
LastNotificationUpdateId++;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -18,392 +18,435 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading;
using Duplicati.Library.Utility;
using Duplicati.Server.Serialization.Interface;
namespace Duplicati.Server
{
/// <summary>
/// This class handles scheduled runs of backups
/// </summary>
public class Scheduler
{
private static readonly string LOGTAG = Duplicati.Library.Logging.Log.LogTagFromType<Scheduler>();
/// <summary>
/// The thread that runs the scheduler
/// </summary>
private readonly Thread m_thread;
/// <summary>
/// A termination flag
/// </summary>
private volatile bool m_terminate;
/// <summary>
/// The worker thread that is invoked to do work
/// </summary>
private readonly WorkerThread<Runner.IRunnerData> m_worker;
/// <summary>
/// The wait event
/// </summary>
private readonly AutoResetEvent m_event;
/// <summary>
/// The data synchronization lock
/// </summary>
private readonly object m_lock = new object();
/// <summary>
/// An event that is raised when the schedule changes
/// </summary>
public event EventHandler NewSchedule;
/// <summary>
/// The currently scheduled items
/// </summary>
private KeyValuePair<DateTime, ISchedule>[] m_schedule;
/// <summary>
/// List of update tasks, used to set the timestamp on the schedule once completed
/// </summary>
private readonly Dictionary<Server.Runner.IRunnerData, Tuple<ISchedule, DateTime, DateTime>> m_updateTasks;
/// <summary>
/// Constructs a new scheduler
/// </summary>
/// <param name="worker">The worker thread</param>
public Scheduler(WorkerThread<Server.Runner.IRunnerData> worker)
{
m_thread = new Thread(new ThreadStart(Runner));
m_worker = worker;
m_worker.CompletedWork += OnCompleted;
m_worker.StartingWork += OnStartingWork;
m_schedule = new KeyValuePair<DateTime, ISchedule>[0];
m_terminate = false;
m_event = new AutoResetEvent(false);
m_updateTasks = new Dictionary<Server.Runner.IRunnerData, Tuple<ISchedule, DateTime, DateTime>>();
m_thread.IsBackground = true;
m_thread.Name = "TaskScheduler";
m_thread.Start();
}
/// <summary>
/// Forces the scheduler to re-evaluate the order.
/// Call this method if something changes
/// </summary>
public void Reschedule()
{
m_event.Set();
}
/// <summary>
/// A snapshot copy of the current schedule list
/// </summary>
public List<KeyValuePair<DateTime, ISchedule>> Schedule
{
get
{
lock (m_lock)
return m_schedule.ToList();
}
}
/// <summary>
/// A snapshot copy of the current worker queue, that is items that are scheduled, but waiting for execution
/// </summary>
public List<Runner.IRunnerData> WorkerQueue
{
get
{
return (from t in m_worker.CurrentTasks where t != null select t).ToList();
}
}
/// <summary>
/// Terminates the thread. Any items still in queue will be removed
/// </summary>
/// <param name="wait">True if the call should block until the thread has exited, false otherwise</param>
public void Terminate(bool wait)
{
m_terminate = true;
m_event.Set();
if (wait)
m_thread.Join();
}
/// <summary>
/// Returns the next valid date, given the start and the interval
/// </summary>
/// <param name="basetime">The base time</param>
/// <param name="firstdate">The first allowed date</param>
/// <param name="repetition">The repetition interval</param>
/// <param name="allowedDays">The days the backup is allowed to run</param>
/// <returns>The next valid date, or throws an exception if no such date can be found</returns>
public static DateTime GetNextValidTime(DateTime basetime, DateTime firstdate, string repetition, DayOfWeek[] allowedDays)
{
var res = basetime;
var i = 50000;
while (res < firstdate && i-- > 0)
res = Timeparser.ParseTimeInterval(repetition, res);
// If we arrived somewhere after the first allowed date
if (res >= firstdate)
{
var ts = Timeparser.ParseTimeSpan(repetition);
if (ts.TotalDays >= 1)
{
// We jump in days, so we pick the first valid day after firstdate
for (var n = 0; n < 8; n++)
if (IsDateAllowed(res, allowedDays))
break;
else
res = res.AddDays(1);
}
else
{
// We jump less than a day, so we keep adding the repetition until
// we hit a valid day
i = 50000;
while (!IsDateAllowed(res, allowedDays) && i-- > 0)
res = Timeparser.ParseTimeInterval(repetition, res);
}
}
if (!IsDateAllowed(res, allowedDays) || res < firstdate)
{
StringBuilder sb = new StringBuilder();
if (allowedDays != null)
foreach (DayOfWeek w in allowedDays)
{
if (sb.Length != 0)
sb.Append(", ");
sb.Append(w.ToString());
}
throw new Exception(Strings.Scheduler.InvalidTimeSetupError(basetime, repetition, sb.ToString()));
}
return res;
}
private void OnCompleted(WorkerThread<Runner.IRunnerData> worker, Runner.IRunnerData task)
{
Tuple<ISchedule, DateTime, DateTime> t = null;
lock(m_lock)
{
if (task != null && m_updateTasks.TryGetValue(task, out t))
m_updateTasks.Remove(task);
}
if (t != null)
{
t.Item1.Time = t.Item2;
t.Item1.LastRun = t.Item3;
Program.DataConnection.AddOrUpdateSchedule(t.Item1);
}
}
private void OnStartingWork(WorkerThread<Runner.IRunnerData> worker, Runner.IRunnerData task)
{
if (task is null)
{
return;
}
lock(m_lock)
{
if (m_updateTasks.TryGetValue(task, out Tuple<ISchedule, DateTime, DateTime> scheduleInfo))
{
// Item2 is the scheduled start time (Time in the Schedule table).
// Item3 is the actual start time (LastRun in the Schedule table).
m_updateTasks[task] = Tuple.Create(scheduleInfo.Item1, scheduleInfo.Item2, DateTime.UtcNow);
}
}
}
/// <summary>
/// The actual scheduling procedure
/// </summary>
private void Runner()
{
var scheduled = new Dictionary<long, KeyValuePair<long, DateTime>>();
while (!m_terminate)
{
//TODO: As this is executed repeatedly we should cache it
// to avoid frequent db lookups
//Determine schedule list
var lst = Program.DataConnection.Schedules;
foreach(var sc in lst)
{
if (!string.IsNullOrEmpty(sc.Repeat))
{
KeyValuePair<long, DateTime> startkey;
DateTime last = new DateTime(0, DateTimeKind.Utc);
DateTime start;
var scticks = sc.Time.Ticks;
if (!scheduled.TryGetValue(sc.ID, out startkey) || startkey.Key != scticks)
{
start = new DateTime(scticks, DateTimeKind.Utc);
last = sc.LastRun;
}
else
{
start = startkey.Value;
}
try
{
// Recover from timedrift issues by overriding the dates if the last run date is in the future.
if (last > DateTime.UtcNow)
{
start = DateTime.UtcNow;
last = DateTime.UtcNow;
}
start = GetNextValidTime(start, last, sc.Repeat, sc.AllowedDays);
}
catch (Exception ex)
{
Program.DataConnection.LogError(sc.ID.ToString(), "Scheduler failed to find next date", ex);
}
//If time is exceeded, run it now
if (start <= DateTime.UtcNow)
{
var jobsToRun = new List<Server.Runner.IRunnerData>();
//TODO: Cache this to avoid frequent lookups
foreach(var id in Program.DataConnection.GetBackupIDsForTags(sc.Tags).Distinct().Select(x => x.ToString()))
{
//See if it is already queued
var tmplst = from n in m_worker.CurrentTasks
where n.Operation == Duplicati.Server.Serialization.DuplicatiOperation.Backup
select n.Backup;
var tastTemp = m_worker.CurrentTask;
if (tastTemp != null && tastTemp.Operation == Duplicati.Server.Serialization.DuplicatiOperation.Backup)
tmplst = tmplst.Union(new [] { tastTemp.Backup });
//If it is not already in queue, put it there
if (!tmplst.Any(x => x.ID == id))
{
var entry = Program.DataConnection.GetBackup(id);
if (entry != null)
{
Dictionary<string, string> options = Duplicati.Server.Runner.GetCommonOptions();
Duplicati.Server.Runner.ApplyOptions(entry, options);
if ((new Duplicati.Library.Main.Options(options)).DisableOnBattery && (Duplicati.Library.Utility.Power.PowerSupply.GetSource() == Duplicati.Library.Utility.Power.PowerSupply.Source.Battery))
{
Duplicati.Library.Logging.Log.WriteInformationMessage(LOGTAG, "BackupDisabledOnBattery", "Scheduled backup disabled while on battery power.");
}
else
{
jobsToRun.Add(Server.Runner.CreateTask(Duplicati.Server.Serialization.DuplicatiOperation.Backup, entry));
}
}
}
}
// Calculate next time, by finding the first entry later than now
try
{
start = GetNextValidTime(start, new DateTime(Math.Max(DateTime.UtcNow.AddSeconds(1).Ticks, start.AddSeconds(1).Ticks), DateTimeKind.Utc), sc.Repeat, sc.AllowedDays);
}
catch(Exception ex)
{
Program.DataConnection.LogError(sc.ID.ToString(), "Scheduler failed to find next date", ex);
continue;
}
Server.Runner.IRunnerData lastJob = jobsToRun.LastOrDefault();
if (lastJob != null)
{
lock (m_lock)
{
// The actual last run time will be updated when the StartingWork event is raised.
m_updateTasks[lastJob] = new Tuple<ISchedule, DateTime, DateTime>(sc, start, DateTime.UtcNow);
}
}
foreach (var job in jobsToRun)
m_worker.AddTask(job);
if (start < DateTime.UtcNow)
{
//TODO: Report this somehow
continue;
}
}
scheduled[sc.ID] = new KeyValuePair<long,DateTime>(scticks, start);
}
}
var existing = lst.ToDictionary(x => x.ID);
//Sort them, lock as we assign the m_schedule variable
lock(m_lock)
m_schedule = (from n in scheduled
where existing.ContainsKey(n.Key)
orderby n.Value.Value
select new KeyValuePair<DateTime, ISchedule>(n.Value.Value, existing[n.Key])).ToArray();
// Remove unused entries
foreach(var c in (from n in scheduled where !existing.ContainsKey(n.Key) select n.Key).ToArray())
scheduled.Remove(c);
//Raise event if needed
if (NewSchedule != null)
NewSchedule(this, null);
int waittime = 0;
//Figure out a sensible amount of time to sleep the thread
if (scheduled.Count > 0)
{
//When is the next run scheduled?
TimeSpan nextrun = scheduled.Values.Min((x) => x.Value) - DateTime.UtcNow;
if (nextrun.TotalMilliseconds < 0)
continue;
//Don't sleep for more than 5 minutes
waittime = (int)Math.Min(nextrun.TotalMilliseconds, 60 * 1000 * 5);
}
else
{
//No tasks, check back later
waittime = 60 * 1000;
}
//Waiting on the event, enables a wakeup call from termination
// never use waittime = 0
m_event.WaitOne(Math.Max(100, waittime), false);
}
}
/// <summary>
/// Returns true if the time is at an allowed weekday, false otherwise
/// </summary>
/// <param name="time">The time to evaluate</param>
/// <param name="allowedDays">The allowed days</param>
/// <returns>True if the backup is allowed to run, false otherwise</returns>
private static bool IsDateAllowed(DateTime time, DayOfWeek[] allowedDays)
{
var localTime = time.ToLocalTime();
if (allowedDays == null || allowedDays.Length == 0)
return true;
else
return Array.IndexOf<DayOfWeek>(allowedDays, localTime.DayOfWeek) >= 0;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading;
using Duplicati.Library.Utility;
using Duplicati.Library.RestAPI;
// TODO: Rewrite this class.
// It should just signal what new backups to run, and not mix with the worker thread.
namespace Duplicati.Server
{
/// <summary>
/// This class handles scheduled runs of backups
/// </summary>
public class Scheduler
{
private static readonly string LOGTAG = Duplicati.Library.Logging.Log.LogTagFromType<Scheduler>();
/// <summary>
/// The thread that runs the scheduler
/// </summary>
private Thread m_thread;
/// <summary>
/// A termination flag
/// </summary>
private volatile bool m_terminate;
/// <summary>
/// The worker thread that is invoked to do work
/// </summary>
private WorkerThread<Runner.IRunnerData> m_worker;
/// <summary>
/// The wait event
/// </summary>
private AutoResetEvent m_event;
/// <summary>
/// The data synchronization lock
/// </summary>
private readonly object m_lock = new object();
/// <summary>
/// An event that is raised when the schedule changes
/// </summary>
public event EventHandler NewSchedule;
/// <summary>
/// The currently scheduled items
/// </summary>
private KeyValuePair<DateTime, ISchedule>[] m_schedule;
/// <summary>
/// List of update tasks, used to set the timestamp on the schedule once completed
/// </summary>
private Dictionary<Server.Runner.IRunnerData, Tuple<ISchedule, DateTime, DateTime>> m_updateTasks;
/// <summary>
/// Constructs a new scheduler
/// </summary>
public Scheduler()
{
}
/// <summary>
/// Initializes scheduler
/// </summary>
/// <param name="worker">The worker thread</param>
public void Init(WorkerThread<Runner.IRunnerData> worker)
{
m_thread = new Thread(new ThreadStart(Runner));
m_worker = worker;
m_worker.CompletedWork += OnCompleted;
m_worker.StartingWork += OnStartingWork;
m_schedule = new KeyValuePair<DateTime, ISchedule>[0];
m_terminate = false;
m_event = new AutoResetEvent(false);
m_updateTasks = new Dictionary<Server.Runner.IRunnerData, Tuple<ISchedule, DateTime, DateTime>>();
m_thread.IsBackground = true;
m_thread.Name = "TaskScheduler";
m_thread.Start();
}
public IList<Tuple<long, string>> GetSchedulerQueueIds()
{
return (from n in WorkerQueue
where n.Backup != null
select new Tuple<long, string>(n.TaskID, n.Backup.ID)).ToList();
}
/// <summary>
/// Forces the scheduler to re-evaluate the order.
/// Call this method if something changes
/// </summary>
public void Reschedule()
{
m_event.Set();
}
/// <summary>
/// A snapshot copy of the current schedule list
/// </summary>
public List<KeyValuePair<DateTime, ISchedule>> Schedule
{
get
{
lock (m_lock)
return m_schedule.ToList();
}
}
/// <summary>
/// A snapshot copy of the current worker queue, that is items that are scheduled, but waiting for execution
/// </summary>
public List<Runner.IRunnerData> WorkerQueue
{
get { return (from t in m_worker.CurrentTasks where t != null select t).ToList(); }
}
/// <summary>
/// Terminates the thread. Any items still in queue will be removed
/// </summary>
/// <param name="wait">True if the call should block until the thread has exited, false otherwise</param>
public void Terminate(bool wait)
{
m_terminate = true;
m_event.Set();
if (wait)
{
try
{
m_thread.Join();
}
catch
{
}
}
}
/// <summary>
/// Returns the next valid date, given the start and the interval
/// </summary>
/// <param name="basetime">The base time</param>
/// <param name="firstdate">The first allowed date</param>
/// <param name="repetition">The repetition interval</param>
/// <param name="allowedDays">The days the backup is allowed to run</param>
/// <returns>The next valid date, or throws an exception if no such date can be found</returns>
public static DateTime GetNextValidTime(DateTime basetime, DateTime firstdate, string repetition,
DayOfWeek[] allowedDays)
{
var res = basetime;
var i = 50000;
while (res < firstdate && i-- > 0)
res = Timeparser.ParseTimeInterval(repetition, res);
// If we arrived somewhere after the first allowed date
if (res >= firstdate)
{
var ts = Timeparser.ParseTimeSpan(repetition);
if (ts.TotalDays >= 1)
{
// We jump in days, so we pick the first valid day after firstdate
for (var n = 0; n < 8; n++)
if (IsDateAllowed(res, allowedDays))
break;
else
res = res.AddDays(1);
}
else
{
// We jump less than a day, so we keep adding the repetition until
// we hit a valid day
i = 50000;
while (!IsDateAllowed(res, allowedDays) && i-- > 0)
res = Timeparser.ParseTimeInterval(repetition, res);
}
}
if (!IsDateAllowed(res, allowedDays) || res < firstdate)
{
StringBuilder sb = new StringBuilder();
if (allowedDays != null)
foreach (DayOfWeek w in allowedDays)
{
if (sb.Length != 0)
sb.Append(", ");
sb.Append(w.ToString());
}
throw new Exception(Strings.Scheduler.InvalidTimeSetupError(basetime, repetition, sb.ToString()));
}
return res;
}
private void OnCompleted(WorkerThread<Runner.IRunnerData> worker, Runner.IRunnerData task)
{
Tuple<ISchedule, DateTime, DateTime> t = null;
lock (m_lock)
{
if (task != null && m_updateTasks.TryGetValue(task, out t))
m_updateTasks.Remove(task);
}
if (t != null)
{
t.Item1.Time = t.Item2;
t.Item1.LastRun = t.Item3;
FIXMEGlobal.DataConnection.AddOrUpdateSchedule(t.Item1);
}
}
private void OnStartingWork(WorkerThread<Runner.IRunnerData> worker, Runner.IRunnerData task)
{
if (task is null)
{
return;
}
lock (m_lock)
{
if (m_updateTasks.TryGetValue(task, out Tuple<ISchedule, DateTime, DateTime> scheduleInfo))
{
// Item2 is the scheduled start time (Time in the Schedule table).
// Item3 is the actual start time (LastRun in the Schedule table).
m_updateTasks[task] = Tuple.Create(scheduleInfo.Item1, scheduleInfo.Item2, DateTime.UtcNow);
}
}
}
/// <summary>
/// The actual scheduling procedure
/// </summary>
private void Runner()
{
var scheduled = new Dictionary<long, KeyValuePair<long, DateTime>>();
while (!m_terminate)
{
//TODO: As this is executed repeatedly we should cache it
// to avoid frequent db lookups
//Determine schedule list
var lst = FIXMEGlobal.DataConnection.Schedules;
foreach (var sc in lst)
{
if (!string.IsNullOrEmpty(sc.Repeat))
{
KeyValuePair<long, DateTime> startkey;
DateTime last = new DateTime(0, DateTimeKind.Utc);
DateTime start;
var scticks = sc.Time.Ticks;
if (!scheduled.TryGetValue(sc.ID, out startkey) || startkey.Key != scticks)
{
start = new DateTime(scticks, DateTimeKind.Utc);
last = sc.LastRun;
}
else
{
start = startkey.Value;
}
try
{
// Recover from timedrift issues by overriding the dates if the last run date is in the future.
if (last > DateTime.UtcNow)
{
start = DateTime.UtcNow;
last = DateTime.UtcNow;
}
start = GetNextValidTime(start, last, sc.Repeat, sc.AllowedDays);
}
catch (Exception ex)
{
FIXMEGlobal.DataConnection.LogError(sc.ID.ToString(), "Scheduler failed to find next date",
ex);
}
//If time is exceeded, run it now
if (start <= DateTime.UtcNow)
{
var jobsToRun = new List<Server.Runner.IRunnerData>();
//TODO: Cache this to avoid frequent lookups
foreach (var id in FIXMEGlobal.DataConnection.GetBackupIDsForTags(sc.Tags).Distinct()
.Select(x => x.ToString()))
{
//See if it is already queued
var tmplst = from n in m_worker.CurrentTasks
where n.Operation == Duplicati.Server.Serialization.DuplicatiOperation.Backup
select n.Backup;
var tastTemp = m_worker.CurrentTask;
if (tastTemp != null && tastTemp.Operation ==
Duplicati.Server.Serialization.DuplicatiOperation.Backup)
tmplst = tmplst.Union(new[] { tastTemp.Backup });
//If it is not already in queue, put it there
if (!tmplst.Any(x => x.ID == id))
{
var entry = FIXMEGlobal.DataConnection.GetBackup(id);
if (entry != null)
{
Dictionary<string, string> options = Duplicati.Server.Runner.GetCommonOptions();
Duplicati.Server.Runner.ApplyOptions(entry, options);
if ((new Duplicati.Library.Main.Options(options)).DisableOnBattery &&
(Duplicati.Library.Utility.Power.PowerSupply.GetSource() ==
Duplicati.Library.Utility.Power.PowerSupply.Source.Battery))
{
Duplicati.Library.Logging.Log.WriteInformationMessage(LOGTAG,
"BackupDisabledOnBattery",
"Scheduled backup disabled while on battery power.");
}
else
{
jobsToRun.Add(Server.Runner.CreateTask(
Duplicati.Server.Serialization.DuplicatiOperation.Backup, entry));
}
}
}
}
// Calculate next time, by finding the first entry later than now
try
{
start = GetNextValidTime(start,
new DateTime(
Math.Max(DateTime.UtcNow.AddSeconds(1).Ticks, start.AddSeconds(1).Ticks),
DateTimeKind.Utc), sc.Repeat, sc.AllowedDays);
}
catch (Exception ex)
{
FIXMEGlobal.DataConnection.LogError(sc.ID.ToString(),
"Scheduler failed to find next date", ex);
continue;
}
Server.Runner.IRunnerData lastJob = jobsToRun.LastOrDefault();
if (lastJob != null)
{
lock (m_lock)
{
// The actual last run time will be updated when the StartingWork event is raised.
m_updateTasks[lastJob] =
new Tuple<ISchedule, DateTime, DateTime>(sc, start, DateTime.UtcNow);
}
}
foreach (var job in jobsToRun)
m_worker.AddTask(job);
if (start < DateTime.UtcNow)
{
//TODO: Report this somehow
continue;
}
}
scheduled[sc.ID] = new KeyValuePair<long, DateTime>(scticks, start);
}
}
var existing = lst.ToDictionary(x => x.ID);
//Sort them, lock as we assign the m_schedule variable
lock (m_lock)
m_schedule = (from n in scheduled
where existing.ContainsKey(n.Key)
orderby n.Value.Value
select new KeyValuePair<DateTime, ISchedule>(n.Value.Value, existing[n.Key])).ToArray();
// Remove unused entries
foreach (var c in (from n in scheduled where !existing.ContainsKey(n.Key) select n.Key).ToArray())
scheduled.Remove(c);
//Raise event if needed
// TODO: This triggers a new data event and a reconnect with long-poll
if (NewSchedule != null)
NewSchedule(this, null);
int waittime = 0;
//Figure out a sensible amount of time to sleep the thread
if (scheduled.Count > 0)
{
//When is the next run scheduled?
TimeSpan nextrun = scheduled.Values.Min((x) => x.Value) - DateTime.UtcNow;
if (nextrun.TotalMilliseconds < 0)
continue;
//Don't sleep for more than 5 minutes
waittime = (int)Math.Min(nextrun.TotalMilliseconds, 60 * 1000 * 5);
}
else
{
// TODO: This should be handled with events, instead of one wakeup per minute
//No tasks, check back later
waittime = 60 * 1000;
}
//Waiting on the event, enables a wakeup call from termination
// never use waittime = 0
m_event.WaitOne(Math.Max(100, waittime), false);
}
}
/// <summary>
/// Returns true if the time is at an allowed weekday, false otherwise
/// </summary>
/// <param name="time">The time to evaluate</param>
/// <param name="allowedDays">The allowed days</param>
/// <returns>True if the backup is allowed to run, false otherwise</returns>
private static bool IsDateAllowed(DateTime time, DayOfWeek[] allowedDays)
{
var localTime = time.ToLocalTime();
if (allowedDays == null || allowedDays.Length == 0)
return true;
else
return Array.IndexOf<DayOfWeek>(allowedDays, localTime.DayOfWeek) >= 0;
}
}
}
@@ -18,7 +18,6 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
namespace Duplicati.Server.Serializable
@@ -1,242 +1,242 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using Duplicati.Server.Serialization.Interface;
namespace Duplicati.Server.Serializable
{
/// <summary>
/// The server config
/// </summary>
public static class ServerSettings
{
/// <summary>
/// Shared implementation for reporting dynamic modules
/// </summary>
private class DynamicModule : IDynamicModule
{
/// <summary>
/// Constructor for backend interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.IBackend backend)
{
this.Key = backend.ProtocolKey;
this.Description = backend.Description;
this.DisplayName = backend.DisplayName;
if (backend.SupportedCommands != null)
this.Options = backend.SupportedCommands.ToArray();
}
/// <summary>
/// Constructor for compression module interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.ICompression module)
{
this.Key = module.FilenameExtension;
this.Description = module.Description;
this.DisplayName = module.DisplayName;
if (module.SupportedCommands != null)
this.Options = module.SupportedCommands.ToArray();
}
/// <summary>
/// Constructor for encryption module interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.IEncryption module)
{
this.Key = module.FilenameExtension;
this.Description = module.Description;
this.DisplayName = module.DisplayName;
if (module.SupportedCommands != null)
this.Options = module.SupportedCommands.ToArray();
}
/// <summary>
/// Constructor for generic module interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.IGenericModule module)
{
this.Key = module.Key;
this.Description = module.Description;
this.DisplayName = module.DisplayName;
if (module.SupportedCommands != null)
this.Options = module.SupportedCommands.ToArray();
}
/// <summary>
/// Constructor for webmodule interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.IWebModule module)
{
this.Key = module.Key;
this.Description = module.Description;
this.DisplayName = module.DisplayName;
if (module.SupportedCommands != null)
this.Options = module.SupportedCommands.ToArray();
}
/// <summary>
/// The module key
/// </summary>
public string Key { get; private set; }
/// <summary>
/// The localized module description
/// </summary>
public string Description { get; private set; }
/// <summary>
/// Gets the localized display name
/// </summary>
/// <value>The display name.</value>
public string DisplayName { get; private set; }
/// <summary>
/// The options supported by the module
/// </summary>
public Duplicati.Library.Interface.ICommandLineArgument[] Options { get; private set; }
}
/// <summary>
/// Gets all supported options
/// </summary>
public static Duplicati.Library.Interface.ICommandLineArgument[] Options
{
get
{
return new Duplicati.Library.Main.Options(new System.Collections.Generic.Dictionary<string, string>()).SupportedCommands.ToArray();
}
}
/// <summary>
/// The backend modules known by the server
/// </summary>
public static IDynamicModule[] BackendModules
{
get
{
return
(from n in Library.DynamicLoader.BackendLoader.Backends
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The encryption modules known by the server
/// </summary>
public static IDynamicModule[] EncryptionModules
{
get
{
return
(from n in Library.DynamicLoader.EncryptionLoader.Modules
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The compression modules known by the server
/// </summary>
public static IDynamicModule[] CompressionModules
{
get
{
return
(from n in Library.DynamicLoader.CompressionLoader.Modules
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The generic modules known by the server
/// </summary>
public static IDynamicModule[] GenericModules
{
get
{
return
(from n in Library.DynamicLoader.GenericLoader.Modules
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The web modules known by the server
/// </summary>
public static IDynamicModule[] WebModules
{
get
{
return
(from n in Library.DynamicLoader.WebLoader.Modules
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The web modules known by the server
/// </summary>
public static IDynamicModule[] ConnectionModules
{
get
{
return
(from n in Library.DynamicLoader.GenericLoader.Modules
where n is Library.Interface.IConnectionModule
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The server modules known by the server
/// </summary>
public static object[] ServerModules
{
get
{
return
(from n in Library.DynamicLoader.GenericLoader.Modules
where n is Library.Interface.IGenericServerModule
select n)
.ToArray();
}
}
/// <summary>
/// The filters that are applied to all backups
/// </summary>
public static IFilter[] Filters
{
get { return Program.DataConnection.Filters; }
}
/// <summary>
/// The settings applied to all backups by default
/// </summary>
public static ISetting[] Settings
{
get { return Program.DataConnection.Settings; }
}
}
}
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using Duplicati.Library.RestAPI;
using Duplicati.Server.Serialization.Interface;
namespace Duplicati.Server.Serializable
{
/// <summary>
/// The server config
/// </summary>
public static class ServerSettings
{
/// <summary>
/// Shared implementation for reporting dynamic modules
/// </summary>
private class DynamicModule : IDynamicModule
{
/// <summary>
/// Constructor for backend interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.IBackend backend)
{
this.Key = backend.ProtocolKey;
this.Description = backend.Description;
this.DisplayName = backend.DisplayName;
if (backend.SupportedCommands != null)
this.Options = backend.SupportedCommands.ToArray();
}
/// <summary>
/// Constructor for compression module interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.ICompression module)
{
this.Key = module.FilenameExtension;
this.Description = module.Description;
this.DisplayName = module.DisplayName;
if (module.SupportedCommands != null)
this.Options = module.SupportedCommands.ToArray();
}
/// <summary>
/// Constructor for encryption module interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.IEncryption module)
{
this.Key = module.FilenameExtension;
this.Description = module.Description;
this.DisplayName = module.DisplayName;
if (module.SupportedCommands != null)
this.Options = module.SupportedCommands.ToArray();
}
/// <summary>
/// Constructor for generic module interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.IGenericModule module)
{
this.Key = module.Key;
this.Description = module.Description;
this.DisplayName = module.DisplayName;
if (module.SupportedCommands != null)
this.Options = module.SupportedCommands.ToArray();
}
/// <summary>
/// Constructor for webmodule interface
/// </summary>
public DynamicModule(Duplicati.Library.Interface.IWebModule module)
{
this.Key = module.Key;
this.Description = module.Description;
this.DisplayName = module.DisplayName;
if (module.SupportedCommands != null)
this.Options = module.SupportedCommands.ToArray();
}
/// <summary>
/// The module key
/// </summary>
public string Key { get; private set; }
/// <summary>
/// The localized module description
/// </summary>
public string Description { get; private set; }
/// <summary>
/// Gets the localized display name
/// </summary>
/// <value>The display name.</value>
public string DisplayName { get; private set; }
/// <summary>
/// The options supported by the module
/// </summary>
public Duplicati.Library.Interface.ICommandLineArgument[] Options { get; private set; }
}
/// <summary>
/// Gets all supported options
/// </summary>
public static Duplicati.Library.Interface.ICommandLineArgument[] Options
{
get
{
return new Duplicati.Library.Main.Options(new System.Collections.Generic.Dictionary<string, string>()).SupportedCommands.ToArray();
}
}
/// <summary>
/// The backend modules known by the server
/// </summary>
public static IDynamicModule[] BackendModules
{
get
{
return
(from n in Library.DynamicLoader.BackendLoader.Backends
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The encryption modules known by the server
/// </summary>
public static IDynamicModule[] EncryptionModules
{
get
{
return
(from n in Library.DynamicLoader.EncryptionLoader.Modules
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The compression modules known by the server
/// </summary>
public static IDynamicModule[] CompressionModules
{
get
{
return
(from n in Library.DynamicLoader.CompressionLoader.Modules
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The generic modules known by the server
/// </summary>
public static IDynamicModule[] GenericModules
{
get
{
return
(from n in Library.DynamicLoader.GenericLoader.Modules
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The web modules known by the server
/// </summary>
public static IDynamicModule[] WebModules
{
get
{
return
(from n in Library.DynamicLoader.WebLoader.Modules
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The web modules known by the server
/// </summary>
public static IDynamicModule[] ConnectionModules
{
get
{
return
(from n in Library.DynamicLoader.GenericLoader.Modules
where n is Library.Interface.IConnectionModule
select new DynamicModule(n))
.ToArray();
}
}
/// <summary>
/// The server modules known by the server
/// </summary>
public static object[] ServerModules
{
get
{
return
(from n in Library.DynamicLoader.GenericLoader.Modules
where n is Library.Interface.IGenericServerModule
select n)
.ToArray();
}
}
/// <summary>
/// The filters that are applied to all backups
/// </summary>
public static IFilter[] Filters
{
get { return FIXMEGlobal.DataConnection.Filters; }
}
/// <summary>
/// The settings applied to all backups by default
/// </summary>
public static ISetting[] Settings
{
get { return FIXMEGlobal.DataConnection.Settings; }
}
}
}
@@ -1,148 +1,147 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Collections.Generic;
using Duplicati.Server.Serialization;
namespace Duplicati.Server.Serializable
{
/// <summary>
/// This class collects all reportable status properties into a single class that can be exported as JSON
/// </summary>
public class ServerStatus : Duplicati.Server.Serialization.Interface.IServerStatus
{
public LiveControlState ProgramState
{
get { return EnumConverter.Convert<LiveControlState>(Program.LiveControl.State); }
}
public string UpdatedVersion
{
get
{
var u = Program.DataConnection.ApplicationSettings.UpdatedVersion;
if (u == null)
return null;
Version v;
if (!Version.TryParse(u.Version, out v))
return null;
if (v <= System.Reflection.Assembly.GetExecutingAssembly().GetName().Version)
return null;
return u.Displayname;
}
}
public UpdatePollerStates UpdaterState { get { return Program.UpdatePoller.ThreadState; } }
public bool UpdateReady { get { return Duplicati.Library.AutoUpdater.UpdaterManager.HasUpdateInstalled; } }
public double UpdateDownloadProgress { get { return Program.UpdatePoller.DownloadProgess; } }
public Tuple<long, string> ActiveTask
{
get
{
var t = Program.WorkThread.CurrentTask;
if (t == null)
return null;
else
return new Tuple<long, string>(t.TaskID, t.Backup == null ? null : t.Backup.ID);
}
}
public IList<Tuple<long, string>> SchedulerQueueIds
{
get { return (from n in Program.Scheduler.WorkerQueue where n.Backup != null select new Tuple<long, string>(n.TaskID, n.Backup.ID)).ToList(); }
}
public IList<Tuple<string, DateTime>> ProposedSchedule
{
get
{
return (
from n in Program.Scheduler.Schedule
let backupid = (from t in n.Value.Tags
where t != null && t.StartsWith("ID=", StringComparison.Ordinal)
select t.Substring("ID=".Length)).FirstOrDefault()
where !string.IsNullOrWhiteSpace(backupid)
select new Tuple<string, DateTime>(backupid, n.Key)
).ToList();
}
}
public bool HasWarning { get { return Program.DataConnection.ApplicationSettings.UnackedWarning; } }
public bool HasError { get { return Program.DataConnection.ApplicationSettings.UnackedError; } }
public SuggestedStatusIcon SuggestedStatusIcon
{
get
{
if (this.ActiveTask == null)
{
if (this.ProgramState == LiveControlState.Paused)
return SuggestedStatusIcon.Paused;
if (this.HasError)
return SuggestedStatusIcon.ReadyError;
if (this.HasWarning)
return SuggestedStatusIcon.ReadyWarning;
return SuggestedStatusIcon.Ready;
}
else
{
if (this.ProgramState == LiveControlState.Running)
return SuggestedStatusIcon.Active;
else
return SuggestedStatusIcon.ActivePaused;
}
}
}
public DateTime EstimatedPauseEnd
{
get
{
return Program.LiveControl.EstimatedPauseEnd;
}
}
private long m_lastEventID = Program.StatusEventNotifyer.EventNo;
public long LastEventID
{
get { return m_lastEventID; }
set { m_lastEventID = value; }
}
public long LastDataUpdateID { get { return Program.LastDataUpdateID; } }
public long LastNotificationUpdateID { get { return Program.LastNotificationUpdateID; } }
}
}
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Collections.Generic;
using Duplicati.Server.Serialization;
using Duplicati.Library.RestAPI;
namespace Duplicati.Server.Serializable
{
/// <summary>
/// This class collects all reportable status properties into a single class that can be exported as JSON
/// </summary>
public class ServerStatus(LiveControls liveControls) : Duplicati.Server.Serialization.Interface.IServerStatus
{
public LiveControlState ProgramState
{
get { return EnumConverter.Convert<LiveControlState>(liveControls.State); }
}
public string UpdatedVersion
{
get
{
var u = FIXMEGlobal.DataConnection.ApplicationSettings.UpdatedVersion;
if (u == null)
return null;
Version v;
if (!Version.TryParse(u.Version, out v))
return null;
if (v <= System.Reflection.Assembly.GetExecutingAssembly().GetName().Version)
return null;
return u.Displayname;
}
}
public string UpdateDownloadLink => FIXMEGlobal.DataConnection.ApplicationSettings.UpdatedVersion?.GetUpdateUrls()?.FirstOrDefault();
public UpdatePollerStates UpdaterState { get { return FIXMEGlobal.UpdatePoller.ThreadState; } }
public double UpdateDownloadProgress { get { return FIXMEGlobal.UpdatePoller.DownloadProgess; } }
public Tuple<long, string> ActiveTask
{
get
{
var t = FIXMEGlobal.WorkThread.CurrentTask;
if (t == null)
return null;
else
return new Tuple<long, string>(t.TaskID, t.Backup == null ? null : t.Backup.ID);
}
}
public IList<Tuple<long, string>> SchedulerQueueIds
{
get { return (from n in FIXMEGlobal.Scheduler.WorkerQueue where n.Backup != null select new Tuple<long, string>(n.TaskID, n.Backup.ID)).ToList(); }
}
public IList<Tuple<string, DateTime>> ProposedSchedule
{
get
{
return (
from n in FIXMEGlobal.Scheduler.Schedule
let backupid = (from t in n.Value.Tags
where t != null && t.StartsWith("ID=", StringComparison.Ordinal)
select t.Substring("ID=".Length)).FirstOrDefault()
where !string.IsNullOrWhiteSpace(backupid)
select new Tuple<string, DateTime>(backupid, n.Key)
).ToList();
}
}
public bool HasWarning { get { return FIXMEGlobal.DataConnection.ApplicationSettings.UnackedWarning; } }
public bool HasError { get { return FIXMEGlobal.DataConnection.ApplicationSettings.UnackedError; } }
public SuggestedStatusIcon SuggestedStatusIcon
{
get
{
if (this.ActiveTask == null)
{
if (this.ProgramState == LiveControlState.Paused)
return SuggestedStatusIcon.Paused;
if (this.HasError)
return SuggestedStatusIcon.ReadyError;
if (this.HasWarning)
return SuggestedStatusIcon.ReadyWarning;
return SuggestedStatusIcon.Ready;
}
else
{
if (this.ProgramState == LiveControlState.Running)
return SuggestedStatusIcon.Active;
else
return SuggestedStatusIcon.ActivePaused;
}
}
}
public DateTime EstimatedPauseEnd
{
get
{
return liveControls.EstimatedPauseEnd;
}
}
private long m_lastEventID = FIXMEGlobal.StatusEventNotifyer.EventNo;
public long LastEventID
{
get { return m_lastEventID; }
set { m_lastEventID = value; }
}
public long LastDataUpdateID => FIXMEGlobal.NotificationUpdateService.LastDataUpdateId;
public long LastNotificationUpdateID => FIXMEGlobal.NotificationUpdateService.LastNotificationUpdateId;
}
}
@@ -1,24 +1,4 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -63,9 +43,21 @@ namespace Duplicati.Server.Serializable
/// </summary>
public bool hidden { get; set; }
/// <summary>
/// True if the element has the system file attribute
/// </summary>
public bool systemFile { get; set; }
/// <summary>
/// True if the element is marked as temporary
/// </summary>
public bool temporary { get; set; }
/// <summary>
/// True if the element is a symlink
/// </summary>
public bool symlink { get; set; }
/// <summary>
/// Size of the file. -1 if directory or inaccessible
/// </summary>
public long fileSize { get; set; }
/// <summary>
/// Constructs a new TreeNode
@@ -1,4 +1,4 @@
// Copyright (C) 2024, The Duplicati Team
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -35,7 +35,7 @@ namespace Duplicati.Server
public static string ExpandEnvironmentVariables(string path)
{
foreach(var n in Nodes)
foreach (var n in Nodes)
if (path.StartsWith(n.id, StringComparison.Ordinal))
path = path.Replace(n.id, n.resolvedpath);
return Environment.ExpandEnvironmentVariables(path);
@@ -58,21 +58,21 @@ namespace Duplicati.Server
});
}
public static string TranslateToPath(string str)
public static string TranslateToPath(string str)
{
string res;
if (PathMap.TryGetValue(str, out res))
return res;
return null;
}
public static string TranslateToDisplayString(string str)
public static string TranslateToDisplayString(string str)
{
string res;
if (DisplayMap.TryGetValue(str, out res))
return res;
return null;
}
@@ -113,12 +113,12 @@ namespace Duplicati.Server
{
}
}
static SpecialFolders()
{
var lst = new List<Serializable.TreeNode>();
if (Platform.IsClientWindows)
if (OperatingSystem.IsWindows())
{
TryAdd(lst, Environment.SpecialFolder.MyDocuments, "%MY_DOCUMENTS%", "My Documents");
TryAdd(lst, Environment.SpecialFolder.MyMusic, "%MY_MUSIC%", "My Music");
@@ -151,7 +151,7 @@ namespace Duplicati.Server
Nodes = lst.ToArray();
}
internal static Dictionary<string, string> GetSourceNames(Serialization.Interface.IBackup backup)
public static Dictionary<string, string> GetSourceNames(Serialization.Interface.IBackup backup)
{
if (backup.Sources == null || backup.Sources.Length == 0)
return new Dictionary<string, string>();
@@ -185,7 +185,7 @@ namespace Duplicati.Server
// Handle duplicates
var result = new Dictionary<string, string>();
foreach(var x in sources)
foreach (var x in sources)
result[x.Key] = x.Value;
return result;
@@ -1,77 +1,61 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using Duplicati.Library.Localization.Short;
using System.Linq;
namespace Duplicati.Server.Strings {
internal static class Program {
public static string AnotherInstanceDetected { get { return LC.L(@"Another instance is running, and was notified"); } }
public static string DatabaseOpenError(string message) { return LC.L(@"Failed to create, open or upgrade the database.
Error message: {0}", message); }
public static string HelpCommandDescription { get { return LC.L(@"Displays this help"); } }
public static string HelpDisplayDialog { get { return LC.L(@"Supported commandline arguments:
"); } }
public static string HelpDisplayFormat(string optionname, string optiontext) { return LC.L(@"--{0}: {1}", optionname, optiontext); }
public static string ParametersFileOptionLong2 { get { return LC.L(@"This option can be used to store some or all of the options given to the commandline client. The file must be a plain text file, UTF-8 encoding is preferred. Each line in the file should be of the format --option=value. The special options --{0} and --{1} can be used to override the localpath and the remote destination uri, respectively. The options in this file take precedence over the options provided on the commandline. You cannot specify filters in both the file and on the commandline. Instead, you can use the special --{2}, --{3}, or --{4} options to specify filters inside the parameter file. Each filter must be prefixed with either a + or a -, and multiple filters must be joined with {5} ", "source", "target", "replace-filter", "append-filter", "prepend-filter", System.IO.Path.PathSeparator); } }
public static string ParametersFileOptionShort { get { return LC.L(@"Path to a file with parameters"); } }
public static string FiltersCannotBeUsedWithFileError2 { get { return LC.L(@"Filters cannot be specified on the commandline if filters are also present in the parameter file. Use the special --{0}, --{1}, or --{2} options to specify filters inside the parameter file. Each filter must be prefixed with either a + or a -, and multiple filters must be joined with {3}", "replace-filter", "append-filter", "prepend-filter", System.IO.Path.PathSeparator); } }
public static string FailedToParseParametersFileError(string path, string message) { return LC.L(@"Unable to read the parameters file ""{0}"", reason: {1}", path, message); }
public static string SkippingSourceArgumentsOnNonBackupOperation { get { return @"The --source argument was specified in the parameter file, but the current operation is not a backup operation, so the argument is ignored"; } }
public static string LogfileCommandDescription { get { return LC.L(@"Outputs log information to the file given"); } }
public static string LoglevelCommandDescription { get { return LC.L(@"Determines the amount of information written in the log file"); } }
public static string PortablemodeCommandDescription { get { return LC.L(@"Activates portable mode where the database is placed below the program executable"); } }
public static string SeriousError(string message) { return LC.L(@"A serious error occurred in Duplicati: {0}", message); }
public static string StartupFailure(System.Exception error) { return LC.L(@"Unable to start up, perhaps another process is already running?
Error message: {0}", error); }
public static string UnencrypteddatabaseCommandDescription { get { return LC.L(@"Disables database encryption"); } }
public static string WrongSQLiteVersion(System.Version actualversion, string expectedversion) { return LC.L(@"Unsupported version of SQLite detected ({0}), must be {1} or higher", actualversion, expectedversion); }
public static string WebserverWebrootDescription { get { return LC.L(@"The path to the folder where the static files for the webserver is present. The folder must be located beneath the installation folder"); } }
public static string WebserverPortDescription { get { return LC.L(@"The port the webserver listens on. Multiple values may be supplied with a comma in between."); } }
public static string WebserverCertificateFileDescription { get { return LC.L(@"The certificate and key file in PKCS #12 format the webserver use for SSL. Only RSA/DSA keys are supported."); } }
public static string WebserverCertificatePasswordDescription { get { return LC.L(@"The password for decryption of certificate PKCS #12 file."); } }
public static string WebserverInterfaceDescription { get { return LC.L(@"The interface the webserver listens on. The special values ""*"" and ""any"" means any interface. The special value ""loopback"" means the loopback adapter."); } }
public static string WebserverPasswordDescription { get { return LC.L(@"The password required to access the webserver. This option is saved so you do not need to set it on each run. Setting an empty value disables the password."); } }
public static string WebserverAllowedhostnamesDescription { get { return LC.L(@"The hostnames that are accepted, separated with semicolons. If any of the hostnames are ""*"", all hostnames are allowed and the hostname checking is disabled."); } }
public static string PingpongkeepaliveShort { get { return LC.L(@"Enables the ping-pong responder"); } }
public static string PingpongkeepaliveLong { get { return LC.L(@"When running as a server, the service daemon must verify that the process is responding. If this option is enabled, the server reads stdin and writes a reply to each line read"); } }
public static string LogretentionShort { get { return LC.L(@"Clean up old log data"); } }
public static string LogretentionLong { get { return LC.L(@"Set the time after which log data will be purged from the database."); } }
public static string ServerdatafolderShort { get { return LC.L(@"Sets the folder where settings are stored"); } }
public static string ServerdatafolderLong(string envname) { return LC.L(@"Duplicati needs to store a small database with all settings. Use this option to choose where the settings are stored. This option can also be set with the environment variable {0}.", envname); }
public static string ServerencryptionkeyShort { get { return LC.L(@"Sets the database encryption key"); } }
public static string ServerencryptionkeyLong(string envname, string decryptionoption) { return LC.L(@"This option sets the encryption key used to scramble the local settings database. This option can also be set with the environment variable {0}. Use the option --{1} to disable the database scrambling.", envname, decryptionoption); }
public static string TempdirShort { get { return LC.L(@"Temporary storage folder"); } }
public static string TempdirLong { get { return LC.L(@"This option can be used to supply an alternative folder for temporary storage. By default the system default temporary folder is used. Note that also SQLite will put temporary files in this temporary folder."); } }
}
internal static class Scheduler {
public static string InvalidTimeSetupError(System.DateTime startdate, string interval, string alloweddays) { return LC.L(@"Unable to find a valid date, given the start date {0}, the repetition interval {1} and the allowed days {2}", startdate, interval, alloweddays); }
}
internal static class Server
{
public static string DefectSSLCertInDatabase { get { return @"Unable to create SSL certificate using data from database. Starting without SSL."; } }
public static string StartedServer(string ip, int port) { return LC.L(@"Server has started and is listening on {0}, port {1}", ip, port); }
public static string SSLCertificateFailure(string errormessage) { return LC.L(@"Unable to create SSL certificate using provided parameters. Exception detail: {0}", errormessage); }
public static string ServerStartFailure(IEnumerable<int> portstried) { return LC.L(@"Unable to open a socket for listening, tried ports: {0}", string.Join(",", from n in (portstried ?? new int[0]) select n.ToString())); }
}
}
using System.Collections.Generic;
using Duplicati.Library.Localization.Short;
using System.Linq;
namespace Duplicati.Server.Strings
{
public static class Program
{
public static string AnotherInstanceDetected { get { return LC.L(@"Another instance is running, and was notified"); } }
public static string DatabaseOpenError(string message) { return LC.L(@"Failed to create, open or upgrade the database.
Error message: {0}", message); }
public static string HelpCommandDescription { get { return LC.L(@"Displays this help"); } }
public static string HelpDisplayDialog { get { return LC.L(@"Supported commandline arguments:
"); } }
public static string HelpDisplayFormat(string optionname, string optiontext) { return LC.L(@"--{0}: {1}", optionname, optiontext); }
public static string ParametersFileOptionLong2 { get { return LC.L(@"This option can be used to store some or all of the options given to the commandline client. The file must be a plain text file, UTF-8 encoding is preferred. Each line in the file should be of the format --option=value. The special options --{0} and --{1} can be used to override the localpath and the remote destination uri, respectively. The options in this file take precedence over the options provided on the commandline. You cannot specify filters in both the file and on the commandline. Instead, you can use the special --{2}, --{3}, or --{4} options to specify filters inside the parameter file. Each filter must be prefixed with either a + or a -, and multiple filters must be joined with {5} ", "source", "target", "replace-filter", "append-filter", "prepend-filter", System.IO.Path.PathSeparator); } }
public static string ParametersFileOptionShort { get { return LC.L(@"Path to a file with parameters"); } }
public static string FiltersCannotBeUsedWithFileError2 { get { return LC.L(@"Filters cannot be specified on the commandline if filters are also present in the parameter file. Use the special --{0}, --{1}, or --{2} options to specify filters inside the parameter file. Each filter must be prefixed with either a + or a -, and multiple filters must be joined with {3}", "replace-filter", "append-filter", "prepend-filter", System.IO.Path.PathSeparator); } }
public static string FailedToParseParametersFileError(string path, string message) { return LC.L(@"Unable to read the parameters file ""{0}"", reason: {1}", path, message); }
public static string SkippingSourceArgumentsOnNonBackupOperation { get { return @"The --source argument was specified in the parameter file, but the current operation is not a backup operation, so the argument is ignored"; } }
public static string LogfileCommandDescription { get { return LC.L(@"Outputs log information to the file given"); } }
public static string LoglevelCommandDescription { get { return LC.L(@"Determines the amount of information written in the log file"); } }
public static string PortablemodeCommandDescription { get { return LC.L(@"Activates portable mode where the database is placed below the program executable"); } }
public static string SeriousError(string message) { return LC.L(@"A serious error occurred in Duplicati: {0}", message); }
public static string StartupFailure(System.Exception error) { return LC.L(@"Unable to start up, perhaps another process is already running?
Error message: {0}", error); }
public static string UnencrypteddatabaseCommandDescription { get { return LC.L(@"Disables database encryption"); } }
public static string WrongSQLiteVersion(System.Version actualversion, string expectedversion) { return LC.L(@"Unsupported version of SQLite detected ({0}), must be {1} or higher", actualversion, expectedversion); }
public static string WebserverWebrootDescription { get { return LC.L(@"The path to the folder where the static files for the webserver is present. The folder must be located beneath the installation folder"); } }
public static string WebserverPortDescription { get { return LC.L(@"The port the webserver listens on. Multiple values may be supplied with a comma in between."); } }
public static string WebserverCertificateFileDescription { get { return LC.L(@"The certificate and key file in PKCS #12 format the webserver use for SSL. Only RSA/DSA keys are supported."); } }
public static string WebserverCertificatePasswordDescription { get { return LC.L(@"The password for decryption of certificate PKCS #12 file."); } }
public static string WebserverInterfaceDescription { get { return LC.L(@"The interface the webserver listens on. The special values ""*"" and ""any"" means any interface. The special value ""loopback"" means the loopback adapter."); } }
public static string WebserverPasswordDescription { get { return LC.L(@"The password required to access the webserver. This option is saved so you do not need to set it on each run. Setting an empty value disables the password."); } }
public static string WebserverAllowedhostnamesDescription { get { return LC.L(@"The hostnames that are accepted, separated with semicolons. If any of the hostnames are ""*"", all hostnames are allowed and the hostname checking is disabled."); } }
public static string PingpongkeepaliveShort { get { return LC.L(@"Enables the ping-pong responder"); } }
public static string PingpongkeepaliveLong { get { return LC.L(@"When running as a server, the service daemon must verify that the process is responding. If this option is enabled, the server reads stdin and writes a reply to each line read"); } }
public static string LogretentionShort { get { return LC.L(@"Clean up old log data"); } }
public static string LogretentionLong { get { return LC.L(@"Set the time after which log data will be purged from the database."); } }
public static string ServerdatafolderShort { get { return LC.L(@"Sets the folder where settings are stored"); } }
public static string ServerdatafolderLong(string envname) { return LC.L(@"Duplicati needs to store a small database with all settings. Use this option to choose where the settings are stored. This option can also be set with the environment variable {0}.", envname); }
public static string ServerencryptionkeyShort { get { return LC.L(@"Sets the database encryption key"); } }
public static string ServerencryptionkeyLong(string envname, string decryptionoption) { return LC.L(@"This option sets the encryption key used to scramble the local settings database. This option can also be set with the environment variable {0}. Use the option --{1} to disable the database scrambling.", envname, decryptionoption); }
public static string TempdirShort { get { return LC.L(@"Temporary storage folder"); } }
public static string TempdirLong { get { return LC.L(@"This option can be used to supply an alternative folder for temporary storage. By default the system default temporary folder is used. Note that also SQLite will put temporary files in this temporary folder."); } }
public static string WebserverResetJwtConfigDescription { get { return LC.L(@"Resets the JWT configuration, invalidating any issued login tokens"); } }
}
internal static class Scheduler
{
public static string InvalidTimeSetupError(System.DateTime startdate, string interval, string alloweddays) { return LC.L(@"Unable to find a valid date, given the start date {0}, the repetition interval {1} and the allowed days {2}", startdate, interval, alloweddays); }
}
public static class Server
{
public static string DefectSSLCertInDatabase { get { return @"Unable to create SSL certificate using data from database. Starting without SSL."; } }
public static string StartedServer(string ip, int port) { return LC.L(@"Server has started and is listening on {0}, port {1}", ip, port); }
public static string SSLCertificateFailure(string errormessage) { return LC.L(@"Unable to create SSL certificate using provided parameters. Exception detail: {0}", errormessage); }
public static string ServerStartFailure(IEnumerable<int> portstried) { return LC.L(@"Unable to open a socket for listening, tried ports: {0}", string.Join(",", from n in (portstried ?? new int[0]) select n.ToString())); }
}
}
@@ -1,275 +1,211 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Threading;
using Duplicati.Server.Serialization;
namespace Duplicati.Server
{
/// <summary>
/// The thread that checks on the update server if new versions are available
/// </summary>
public class UpdatePollThread
{
private readonly Thread m_thread;
private volatile bool m_terminated = false;
private volatile bool m_download = false;
private volatile bool m_forceCheck = false;
private readonly object m_lock = new object();
private readonly AutoResetEvent m_waitSignal;
private double m_downloadProgress;
public bool IsUpdateRequested { get; private set; } = false;
public UpdatePollerStates ThreadState { get; private set; }
public double DownloadProgess
{
get { return m_downloadProgress ; }
private set
{
var oldv = m_downloadProgress;
m_downloadProgress = value;
if ((int)(oldv * 100) != (int)(value * 100))
Program.StatusEventNotifyer.SignalNewEvent();
}
}
public UpdatePollThread()
{
m_waitSignal = new AutoResetEvent(false);
ThreadState = UpdatePollerStates.Waiting;
m_thread = new Thread(Run);
m_thread.IsBackground = true;
m_thread.Name = "UpdatePollThread";
m_thread.Start();
}
public void CheckNow()
{
lock(m_lock)
{
m_forceCheck = true;
m_waitSignal.Set();
}
}
public void InstallUpdate()
{
lock(m_lock)
{
m_forceCheck = true;
m_download = true;
m_waitSignal.Set();
}
}
public void ActivateUpdate()
{
if (Duplicati.Library.AutoUpdater.UpdaterManager.SetRunUpdate())
{
IsUpdateRequested = true;
Program.ApplicationExitEvent.Set();
}
}
public void Terminate()
{
lock(m_lock)
{
m_terminated = true;
m_waitSignal.Set();
}
}
public void Reschedule()
{
m_waitSignal.Set();
}
private void Run()
{
// Wait on startup
m_waitSignal.WaitOne(TimeSpan.FromMinutes(1), true);
while (!m_terminated)
{
var nextCheck = Program.DataConnection.ApplicationSettings.NextUpdateCheck;
var maxcheck = TimeSpan.FromDays(7);
try
{
maxcheck = Library.Utility.Timeparser.ParseTimeSpan(Program.DataConnection.ApplicationSettings.UpdateCheckInterval);
}
catch
{
}
// If we have some weirdness, just check now
if (nextCheck - DateTime.UtcNow > maxcheck)
nextCheck = DateTime.UtcNow - TimeSpan.FromSeconds(1);
if (nextCheck < DateTime.UtcNow || m_forceCheck)
{
lock(m_lock)
m_forceCheck = false;
ThreadState = UpdatePollerStates.Checking;
Program.StatusEventNotifyer.SignalNewEvent();
DateTime started = DateTime.UtcNow;
Program.DataConnection.ApplicationSettings.LastUpdateCheck = started;
nextCheck = Program.DataConnection.ApplicationSettings.NextUpdateCheck;
Library.AutoUpdater.ReleaseType rt;
if (!Enum.TryParse<Library.AutoUpdater.ReleaseType>(Program.DataConnection.ApplicationSettings.UpdateChannel, true, out rt))
rt = Duplicati.Library.AutoUpdater.ReleaseType.Unknown;
// Choose the default channel in case we have unknown
rt = rt == Duplicati.Library.AutoUpdater.ReleaseType.Unknown ? Duplicati.Library.AutoUpdater.AutoUpdateSettings.DefaultUpdateChannel : rt;
try
{
var update = Duplicati.Library.AutoUpdater.UpdaterManager.CheckForUpdate(rt);
if (update != null)
Program.DataConnection.ApplicationSettings.UpdatedVersion = update;
}
catch
{
}
// It could be that we have registered an update from a more unstable channel,
// but the user has switched to a more stable channel.
// In that case we discard the old update to avoid offering it.
if (Program.DataConnection.ApplicationSettings.UpdatedVersion != null)
{
Library.AutoUpdater.ReleaseType updatert;
var updatertstring = Program.DataConnection.ApplicationSettings.UpdatedVersion.ReleaseType;
if (string.Equals(updatertstring, "preview", StringComparison.OrdinalIgnoreCase))
updatertstring = Library.AutoUpdater.ReleaseType.Experimental.ToString();
if (!Enum.TryParse<Library.AutoUpdater.ReleaseType>(updatertstring, true, out updatert))
updatert = Duplicati.Library.AutoUpdater.ReleaseType.Nightly;
if (updatert == Duplicati.Library.AutoUpdater.ReleaseType.Unknown)
updatert = Duplicati.Library.AutoUpdater.ReleaseType.Nightly;
if (updatert > rt)
Program.DataConnection.ApplicationSettings.UpdatedVersion = null;
}
if (Program.DataConnection.ApplicationSettings.UpdatedVersion != null && Duplicati.Library.AutoUpdater.UpdaterManager.TryParseVersion(Program.DataConnection.ApplicationSettings.UpdatedVersion.Version) > System.Reflection.Assembly.GetExecutingAssembly().GetName().Version)
{
if (string.IsNullOrWhiteSpace(Program.DataConnection.ApplicationSettings.UpdatedVersion.UpdateFromV1Url))
{
Program.DataConnection.RegisterNotification(
NotificationType.Information,
"Found update",
Program.DataConnection.ApplicationSettings.UpdatedVersion.Displayname,
null,
null,
"update:new",
null,
"NewUpdateFound",
null,
(self, all) => all.FirstOrDefault(x => x.Action == "update:new") ?? self
);
}
else
{
Program.DataConnection.RegisterNotification(
NotificationType.Information,
"Manual update required",
Program.DataConnection.ApplicationSettings.UpdatedVersion.UpdateFromV1Url,
null,
null,
"update:manual",
null,
"NewUpdateFound",
null,
(self, all) => all.FirstOrDefault(x => x.Action == "update:manual") ?? self
);
}
}
}
if (m_download)
{
lock (m_lock)
m_download = false;
var v = Program.DataConnection.ApplicationSettings.UpdatedVersion;
if (v != null)
{
if (string.IsNullOrWhiteSpace(v.UpdateFromV1Url))
{
ThreadState = UpdatePollerStates.Downloading;
Program.StatusEventNotifyer.SignalNewEvent();
if (Duplicati.Library.AutoUpdater.UpdaterManager.DownloadAndUnpackUpdate(v, (pg) => { DownloadProgess = pg; }))
Program.StatusEventNotifyer.SignalNewEvent();
}
else
{
Program.DataConnection.RegisterNotification(
NotificationType.Error,
"Manual update required",
v.UpdateFromV1Url,
null,
null,
"update:manual",
null,
"NewUpdateFound",
null,
(self, all) => all.FirstOrDefault(x => x.Action == "update:manual") ?? self
);
}
}
}
DownloadProgess = 0;
if (ThreadState != UpdatePollerStates.Waiting)
{
ThreadState = UpdatePollerStates.Waiting;
Program.StatusEventNotifyer.SignalNewEvent();
}
var waitTime = nextCheck - DateTime.UtcNow;
// Guard against spin-loop
if (waitTime.TotalSeconds < 5)
waitTime = TimeSpan.FromSeconds(5);
// Guard against year-long waits
// A re-check does not cause an update check
if (waitTime.TotalDays > 1)
waitTime = TimeSpan.FromDays(1);
m_waitSignal.WaitOne(waitTime, true);
}
}
}
}
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Threading;
using Duplicati.Server.Database;
using Duplicati.Server.Serialization;
namespace Duplicati.Server
{
/// <summary>
/// The thread that checks on the update server if new versions are available
/// </summary>
public class UpdatePollThread(Connection connection, EventPollNotify eventPollNotify)
{
private Thread m_thread;
private volatile bool m_terminated = false;
private volatile bool m_forceCheck = false;
private readonly object m_lock = new object();
private AutoResetEvent m_waitSignal;
private double m_downloadProgress;
public bool IsUpdateRequested { get; private set; } = false;
public UpdatePollerStates ThreadState { get; private set; }
public double DownloadProgess
{
get { return m_downloadProgress; }
private set
{
var oldv = m_downloadProgress;
m_downloadProgress = value;
if ((int)(oldv * 100) != (int)(value * 100))
eventPollNotify.SignalNewEvent();
}
}
public void Init()
{
m_waitSignal = new AutoResetEvent(false);
ThreadState = UpdatePollerStates.Waiting;
m_thread = new Thread(Run)
{
IsBackground = true,
Name = "UpdatePollThread"
};
m_thread.Start();
}
public void CheckNow()
{
lock (m_lock)
{
m_forceCheck = true;
m_waitSignal.Set();
}
}
public void Terminate()
{
lock (m_lock)
{
m_terminated = true;
m_waitSignal.Set();
}
}
public void Reschedule()
{
m_waitSignal.Set();
}
private void Run()
{
// Wait on startup
m_waitSignal.WaitOne(TimeSpan.FromMinutes(1), true);
while (!m_terminated)
{
var nextCheck = connection.ApplicationSettings.NextUpdateCheck;
var maxcheck = TimeSpan.FromDays(7);
try
{
maxcheck = Library.Utility.Timeparser.ParseTimeSpan(connection.ApplicationSettings.UpdateCheckInterval);
}
catch
{
}
// If we have some weirdness, just check now
if (nextCheck - DateTime.UtcNow > maxcheck)
nextCheck = DateTime.UtcNow - TimeSpan.FromSeconds(1);
if (nextCheck < DateTime.UtcNow || m_forceCheck)
{
lock (m_lock)
m_forceCheck = false;
ThreadState = UpdatePollerStates.Checking;
eventPollNotify.SignalNewEvent();
DateTime started = DateTime.UtcNow;
connection.ApplicationSettings.LastUpdateCheck = started;
nextCheck = connection.ApplicationSettings.NextUpdateCheck;
Library.AutoUpdater.ReleaseType rt;
if (!Enum.TryParse<Library.AutoUpdater.ReleaseType>(connection.ApplicationSettings.UpdateChannel, true, out rt))
rt = Duplicati.Library.AutoUpdater.ReleaseType.Unknown;
// Choose the default channel in case we have unknown
rt = rt == Duplicati.Library.AutoUpdater.ReleaseType.Unknown ? Duplicati.Library.AutoUpdater.AutoUpdateSettings.DefaultUpdateChannel : rt;
try
{
var update = Duplicati.Library.AutoUpdater.UpdaterManager.CheckForUpdate(rt);
if (update != null)
connection.ApplicationSettings.UpdatedVersion = update;
}
catch
{
}
// It could be that we have registered an update from a more unstable channel,
// but the user has switched to a more stable channel.
// In that case we discard the old update to avoid offering it.
if (connection.ApplicationSettings.UpdatedVersion != null)
{
Library.AutoUpdater.ReleaseType updatert;
var updatertstring = connection.ApplicationSettings.UpdatedVersion.ReleaseType;
if (string.Equals(updatertstring, "preview", StringComparison.OrdinalIgnoreCase))
updatertstring = Library.AutoUpdater.ReleaseType.Experimental.ToString();
if (!Enum.TryParse<Library.AutoUpdater.ReleaseType>(updatertstring, true, out updatert))
updatert = Duplicati.Library.AutoUpdater.ReleaseType.Nightly;
if (updatert == Duplicati.Library.AutoUpdater.ReleaseType.Unknown)
updatert = Duplicati.Library.AutoUpdater.ReleaseType.Nightly;
if (updatert > rt)
connection.ApplicationSettings.UpdatedVersion = null;
}
var updatedinfo = connection.ApplicationSettings.UpdatedVersion;
if (updatedinfo != null && Duplicati.Library.AutoUpdater.UpdaterManager.TryParseVersion(updatedinfo.Version) > System.Reflection.Assembly.GetExecutingAssembly().GetName().Version)
{
var package = updatedinfo.FindPackage();
connection.RegisterNotification(
NotificationType.Information,
"Found update",
updatedinfo.Displayname,
null,
null,
"update:new",
null,
"NewUpdateFound",
null,
(self, all) =>
{
return all.FirstOrDefault(x => x.Action == "update:new") ?? self;
}
);
}
}
DownloadProgess = 0;
if (ThreadState != UpdatePollerStates.Waiting)
{
ThreadState = UpdatePollerStates.Waiting;
eventPollNotify.SignalNewEvent();
}
var waitTime = nextCheck - DateTime.UtcNow;
// Guard against spin-loop
if (waitTime.TotalSeconds < 5)
waitTime = TimeSpan.FromSeconds(5);
// Guard against year-long waits
// A re-check does not cause an update check
if (waitTime.TotalDays > 1)
waitTime = TimeSpan.FromDays(1);
m_waitSignal.WaitOne(waitTime, true);
}
}
}
}
+15
View File
@@ -0,0 +1,15 @@
{
"Backup": {
"Settings": [
{ "Name": "encryption-module", "Value": "aes" },
{ "Name": "compression-module", "Value": "zip" },
{ "Name": "dblock-size", "Value": "50mb" },
{ "Name": "keep-time", "Value": "" }
]
},
"Schedule": {
"Repeat": "1D",
"Time": "13:00:00",
"AllowedDays": ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
}
}
+221 -74
View File
@@ -1,113 +1,156 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31919.166
VisualStudioVersion = 17.1.32210.238
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Utility", "Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Main", "Duplicati\Library\Main\Duplicati.Library.Main.csproj", "{10D2D1B7-C664-41D8-9B3A-00040C3D421B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Main", "Duplicati\Library\Main\Duplicati.Library.Main.csproj", "{10D2D1B7-C664-41D8-9B3A-00040C3D421B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.File", "Duplicati\Library\Backend\File\Duplicati.Library.Backend.File.csproj", "{FC9B7611-836F-4127-8B44-A7C31F506807}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.File", "Duplicati\Library\Backend\File\Duplicati.Library.Backend.File.csproj", "{FC9B7611-836F-4127-8B44-A7C31F506807}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.FTP", "Duplicati\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj", "{F61679A9-E5DE-468A-B5A4-05F92D0143D2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.FTP", "Duplicati\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj", "{F61679A9-E5DE-468A-B5A4-05F92D0143D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Compression", "Duplicati\Library\Compression\Duplicati.Library.Compression.csproj", "{19ECCE09-B5EB-406C-8C57-BAC66997D469}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Compression", "Duplicati\Library\Compression\Duplicati.Library.Compression.csproj", "{19ECCE09-B5EB-406C-8C57-BAC66997D469}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Logging", "Duplicati\Library\Logging\Duplicati.Library.Logging.csproj", "{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Logging", "Duplicati\Library\Logging\Duplicati.Library.Logging.csproj", "{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.S3", "Duplicati\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj", "{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.S3", "Duplicati\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj", "{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine", "Duplicati\CommandLine\Duplicati.CommandLine.csproj", "{81765A64-3661-4E3E-B850-2F6F87A51F74}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine", "Duplicati\CommandLine\CLI\Duplicati.CommandLine.csproj", "{81765A64-3661-4E3E-B850-2F6F87A51F74}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.WEBDAV", "Duplicati\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj", "{BAE27510-8B5D-44B2-B33E-372A98908041}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.WEBDAV", "Duplicati\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj", "{BAE27510-8B5D-44B2-B33E-372A98908041}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.CloudFiles", "Duplicati\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj", "{1BFAE226-8364-4086-825C-BB83F6F3EE4C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.CloudFiles", "Duplicati\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj", "{1BFAE226-8364-4086-825C-BB83F6F3EE4C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.BackendTester", "Duplicati\CommandLine\BackendTester\Duplicati.CommandLine.BackendTester.csproj", "{E7280DCA-7776-4A73-B9B5-41FD77FC8799}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.BackendTester", "Duplicati\CommandLine\BackendTester\Duplicati.CommandLine.BackendTester.csproj", "{E7280DCA-7776-4A73-B9B5-41FD77FC8799}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Interface", "Duplicati\Library\Interface\Duplicati.Library.Interface.csproj", "{C5899F45-B0FF-483C-9D38-24A9FCAAB237}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Interface", "Duplicati\Library\Interface\Duplicati.Library.Interface.csproj", "{C5899F45-B0FF-483C-9D38-24A9FCAAB237}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.DynamicLoader", "Duplicati\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj", "{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.DynamicLoader", "Duplicati\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj", "{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Snapshots", "Duplicati\Library\Snapshots\Duplicati.Library.Snapshots.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACE}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Snapshots", "Duplicati\Library\Snapshots\Duplicati.Library.Snapshots.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.License", "Duplicati\License\Duplicati.License.csproj", "{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.License", "Duplicati\License\Duplicati.License.csproj", "{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Modules.Builtin", "Duplicati\Library\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj", "{52826615-7964-47FE-B4B3-1B2DBDF605B9}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Modules.Builtin", "Duplicati\Library\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj", "{52826615-7964-47FE-B4B3-1B2DBDF605B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.TahoeLAFS", "Duplicati\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj", "{C0270709-2A40-43B5-8CF1-69581B9FA2A1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.TahoeLAFS", "Duplicati\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj", "{C0270709-2A40-43B5-8CF1-69581B9FA2A1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.OneDrive", "Duplicati\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj", "{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.OneDrive", "Duplicati\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj", "{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.SSHv2", "Duplicati\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj", "{FF2BF37C-E502-4C98-BEA0-701671DDFA08}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.SSHv2", "Duplicati\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj", "{FF2BF37C-E502-4C98-BEA0-701671DDFA08}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Server", "Duplicati\Server\Duplicati.Server.csproj", "{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Server", "Duplicati\Server\Duplicati.Server.csproj", "{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.GUI.TrayIcon", "Duplicati\GUI\Duplicati.GUI.TrayIcon\Duplicati.GUI.TrayIcon.csproj", "{17566860-3D98-4604-AA5B-47661F75609F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.GUI.TrayIcon", "Duplicati\GUI\Duplicati.GUI.TrayIcon\Duplicati.GUI.TrayIcon.csproj", "{17566860-3D98-4604-AA5B-47661F75609F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Server.Serialization", "Duplicati\Server\Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj", "{33FD1D24-C28F-4C71-933F-98F1586EA76C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Server.Serialization", "Duplicati\Server\Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj", "{33FD1D24-C28F-4C71-933F-98F1586EA76C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.BackendTool", "Duplicati\CommandLine\BackendTool\Duplicati.CommandLine.BackendTool.csproj", "{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.BackendTool", "Duplicati\CommandLine\BackendTool\Duplicati.CommandLine.BackendTool.csproj", "{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.SQLiteHelper", "Duplicati\Library\SQLiteHelper\Duplicati.Library.SQLiteHelper.csproj", "{2C838169-B187-4B09-8768-1C24C2521C8D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.SQLiteHelper", "Duplicati\Library\SQLiteHelper\Duplicati.Library.SQLiteHelper.csproj", "{2C838169-B187-4B09-8768-1C24C2521C8D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Localization", "Duplicati\Library\Localization\Duplicati.Library.Localization.csproj", "{B68F2214-951F-4F78-8488-66E1ED3F50BF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Localization", "Duplicati\Library\Localization\Duplicati.Library.Localization.csproj", "{B68F2214-951F-4F78-8488-66E1ED3F50BF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.AutoUpdater", "Duplicati\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj", "{7E119745-1F62-43F0-936C-F312A1912C0B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.AutoUpdater", "Duplicati\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj", "{7E119745-1F62-43F0-936C-F312A1912C0B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Service", "Duplicati\Service\Duplicati.Service.csproj", "{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Service", "Duplicati\Service\Duplicati.Service.csproj", "{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AzureBlob", "Duplicati\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj", "{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.AzureBlob", "Duplicati\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj", "{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.UnitTest", "Duplicati\UnitTest\Duplicati.UnitTest.csproj", "{ECB63D1C-1724-442D-9228-DEABF14F2EA3}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.UnitTest", "Duplicati\UnitTest\Duplicati.UnitTest.csproj", "{ECB63D1C-1724-442D-9228-DEABF14F2EA3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.OAuthHelper", "Duplicati\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj", "{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.OAuthHelper", "Duplicati\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj", "{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.GoogleServices", "Duplicati\Library\Backend\GoogleServices\Duplicati.Library.Backend.GoogleServices.csproj", "{5489181D-950C-44AF-873C-45EB0A3B6BD2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.GoogleServices", "Duplicati\Library\Backend\GoogleServices\Duplicati.Library.Backend.GoogleServices.csproj", "{5489181D-950C-44AF-873C-45EB0A3B6BD2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.OpenStack", "Duplicati\Library\Backend\OpenStack\Duplicati.Library.Backend.OpenStack.csproj", "{D9E4E686-423C-48EC-A392-404E7C00860C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.OpenStack", "Duplicati\Library\Backend\OpenStack\Duplicati.Library.Backend.OpenStack.csproj", "{D9E4E686-423C-48EC-A392-404E7C00860C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.RecoveryTool", "Duplicati\CommandLine\RecoveryTool\Duplicati.CommandLine.RecoveryTool.csproj", "{4A010589-76E6-4F05-A5C4-4598D5DF11F8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.RecoveryTool", "Duplicati\CommandLine\RecoveryTool\Duplicati.CommandLine.RecoveryTool.csproj", "{4A010589-76E6-4F05-A5C4-4598D5DF11F8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Backblaze", "Duplicati\Library\Backend\Backblaze\Duplicati.Library.Backend.Backblaze.csproj", "{61C43D61-4368-4942-84A3-1EB623F4EF2A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.Backblaze", "Duplicati\Library\Backend\Backblaze\Duplicati.Library.Backend.Backblaze.csproj", "{61C43D61-4368-4942-84A3-1EB623F4EF2A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Mega", "Duplicati\Library\Backend\Mega\Duplicati.Library.Backend.Mega.csproj", "{6643A5AE-AB38-453F-ADCE-408E35A81A83}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.Mega", "Duplicati\Library\Backend\Mega\Duplicati.Library.Backend.Mega.csproj", "{6643A5AE-AB38-453F-ADCE-408E35A81A83}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Box", "Duplicati\Library\Backend\Box\Duplicati.Library.Backend.Box.csproj", "{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.Box", "Duplicati\Library\Backend\Box\Duplicati.Library.Backend.Box.csproj", "{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.UsageReporter", "Duplicati\Library\UsageReporter\Duplicati.Library.UsageReporter.csproj", "{BB014EA5-CE2C-4444-8D30-38983A0E8553}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.UsageReporter", "Duplicati\Library\UsageReporter\Duplicati.Library.UsageReporter.csproj", "{BB014EA5-CE2C-4444-8D30-38983A0E8553}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.SharePoint", "Duplicati\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj", "{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.SharePoint", "Duplicati\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj", "{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsService", "Duplicati\WindowsService\WindowsService.csproj", "{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.AlternativeFTP", "Duplicati\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj", "{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AlternativeFTP", "Duplicati\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj", "{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.Dropbox", "Duplicati\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj", "{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Dropbox", "Duplicati\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj", "{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Tools", "Duplicati\Tools\Duplicati.Tools.csproj", "{0797AA22-C5DD-4950-BB60-34765AB8C6DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Tools", "Duplicati\Tools\Duplicati.Tools.csproj", "{0797AA22-C5DD-4950-BB60-34765AB8C6DD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.Jottacloud", "Duplicati\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj", "{2CD5DBC3-3DA6-432D-BA97-F0B8D24501C2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Jottacloud", "Duplicati\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj", "{2CD5DBC3-3DA6-432D-BA97-F0B8D24501C2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.Sia", "Duplicati\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj", "{32A74526-3E5F-413A-8CB4-1EFDAD4C8B91}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Sia", "Duplicati\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj", "{32A74526-3E5F-413A-8CB4-1EFDAD4C8B91}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.Rclone", "Duplicati\Library\Backend\Rclone\Duplicati.Library.Backend.Rclone.csproj", "{851A1CB8-3CEB-41B4-956F-34D760D2A8E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Rclone", "Duplicati\Library\Backend\Rclone\Duplicati.Library.Backend.Rclone.csproj", "{851A1CB8-3CEB-41B4-956F-34D760D2A8E5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Common", "Duplicati\Library\Common\Duplicati.Library.Common.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Common", "Duplicati\Library\Common\Duplicati.Library.Common.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.ConfigurationImporter", "Duplicati\CommandLine\ConfigurationImporter\Duplicati.CommandLine.ConfigurationImporter.csproj", "{B93E3BF0-DAA7-49B7-B07D-0559C5816735}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.ConfigurationImporter", "Duplicati\CommandLine\ConfigurationImporter\Duplicati.CommandLine.ConfigurationImporter.csproj", "{B93E3BF0-DAA7-49B7-B07D-0559C5816735}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Encryption", "Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj", "{2CF2D90E-C25B-47AD-91E0-98451BAB8058}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Encryption", "Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj", "{2CF2D90E-C25B-47AD-91E0-98451BAB8058}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.AutoUpdater", "Duplicati\CommandLine\AutoUpdater\Duplicati.CommandLine.AutoUpdater.csproj", "{4D1B198B-F773-44F2-872B-2B283053323C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Storj", "Duplicati\Library\Backend\Storj\Duplicati.Library.Backend.Storj.csproj", "{AE035E01-C917-4F13-A35E-78F21C1A2F17}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.Storj", "Duplicati\Library\Backend\Storj\Duplicati.Library.Backend.Storj.csproj", "{E9AB8491-BD4C-4E4F-84C3-0BD551CC7489}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.TencentCOS", "Duplicati\Library\Backend\TencentCOS\Duplicati.Library.Backend.TencentCOS.csproj", "{545DD6D4-9476-42D6-B51C-A28E000C489E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.TencentCOS", "Duplicati\Library\Backend\TencentCOS\Duplicati.Library.Backend.TencentCOS.csproj", "{545DD6D4-9476-42D6-B51C-A28E000C489E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Tardigrade", "Duplicati\Library\Backend\Tardigrade\Duplicati.Library.Backend.Tardigrade.csproj", "{9A04CB37-DA72-4008-9703-3AC5191974E9}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Executables", "Executables", "{FA88A246-EF8E-46E3-90AF-539B8C0A6ADE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Idrivee2", "Duplicati\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj", "{6B594D23-B629-465C-B799-70EE9E56C218}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "net8", "net8", "{6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AliyunOSS", "Duplicati\Library\Backend\AliyunOSS\Duplicati.Library.Backend.AliyunOSS.csproj", "{4EB3DABC-D412-4C12-8876-41A1427A389E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.AutoUpdater", "Executables\net8\Duplicati.CommandLine.AutoUpdater\Duplicati.CommandLine.AutoUpdater.csproj", "{95B7DD83-2C5A-4F1E-8EA7-39654B2B236A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Service", "Executables\net8\Duplicati.Service\Duplicati.Service.csproj", "{34149709-F3ED-4FB5-A087-43EB195C948B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.BackendTester", "Executables\net8\Duplicati.CommandLine.BackendTester\Duplicati.CommandLine.BackendTester.csproj", "{2F1C0C8D-5C15-4BC0-811F-87F2C98D9790}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.BackendTool", "Executables\net8\Duplicati.CommandLine.BackendTool\Duplicati.CommandLine.BackendTool.csproj", "{31FA5B9B-4CD6-4BF3-B7A9-12C1E30DCAF6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.ConfigurationImporter", "Executables\net8\Duplicati.CommandLine.ConfigurationImporter\Duplicati.CommandLine.ConfigurationImporter.csproj", "{156B9B77-C2B7-4169-8FE7-1171D221446C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine.RecoveryTool", "Executables\net8\Duplicati.CommandLine.RecoveryTool\Duplicati.CommandLine.RecoveryTool.csproj", "{0FFC557E-1B84-46A2-B6E8-06064FA7EA58}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.GUI.TrayIcon", "Executables\net8\Duplicati.GUI.TrayIcon\Duplicati.GUI.TrayIcon.csproj", "{AF32C621-30DC-40F5-8CE6-DD69053068E9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Server", "Executables\net8\Duplicati.Server\Duplicati.Server.csproj", "{55EEEBD2-CE45-45D6-9838-958F1C7354E4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowsService", "Duplicati\WindowsService\WindowsService.csproj", "{8A651E2D-A7C8-4EC7-B421-7A457654811D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.WindowsService", "Executables\net8\Duplicati.WindowsService\Duplicati.WindowsService.csproj", "{5D20B150-C445-47BE-8CE8-C9F74F19A4F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.CommandLine", "Executables\net8\Duplicati.CommandLine\Duplicati.CommandLine.csproj", "{0F5A1F4E-25FA-4D02-920D-CA2138498081}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.Idrivee2", "Duplicati\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj", "{6B594D23-B629-465C-B799-70EE9E56C218}"
ProjectSection(ProjectDependencies) = postProject
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2} = {C03F6DFD-805A-4BE0-9338-64870ADDB4A2}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Backends", "Backends", "{E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Helper Libraries", "Helper Libraries", "{566EBBDA-19A4-4056-A615-D901D57D2439}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Implementation", "Implementation", "{D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backends", "Duplicati\Library\Backends\Duplicati.Library.Backends.csproj", "{5290E237-C2CD-48F2-99D2-817F9C2163C8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.WebserverCore", "Duplicati\WebserverCore\Duplicati.WebserverCore.csproj", "{5A702CEE-DB36-4153-BD94-D8CF867E75A9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.RestAPI", "Duplicati.Library.RestAPI\Duplicati.Library.RestAPI.csproj", "{C1D4D665-23A3-4216-9CD1-D67AE9AAAA4C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Duplicati.Library.Backend.AliyunOSS", "Duplicati\Library\Backend\AliyunOSS\Duplicati.Library.Backend.AliyunOSS.csproj", "{4EB3DABC-D412-4C12-8876-41A1427A389E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.SharpAESCrypt", "Executables\net8\Duplicati.CommandLine.SharpAESCrypt\Duplicati.CommandLine.SharpAESCrypt.csproj", "{FE6FD36C-E171-4599-8D55-62DA579C0864}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.Snapshots", "Executables\net8\Duplicati.CommandLine.Snapshots\Duplicati.CommandLine.Snapshots.csproj", "{0364E724-1929-445E-9145-90A70B01DDC0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -267,10 +310,6 @@ Global
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Release|Any CPU.Build.0 = Release|Any CPU
{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}.Release|Any CPU.Build.0 = Release|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -307,30 +346,142 @@ Global
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Release|Any CPU.Build.0 = Release|Any CPU
{AE035E01-C917-4F13-A35E-78F21C1A2F17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE035E01-C917-4F13-A35E-78F21C1A2F17}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE035E01-C917-4F13-A35E-78F21C1A2F17}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE035E01-C917-4F13-A35E-78F21C1A2F17}.Release|Any CPU.Build.0 = Release|Any CPU
{4D1B198B-F773-44F2-872B-2B283053323C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D1B198B-F773-44F2-872B-2B283053323C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D1B198B-F773-44F2-872B-2B283053323C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D1B198B-F773-44F2-872B-2B283053323C}.Release|Any CPU.Build.0 = Release|Any CPU
{E9AB8491-BD4C-4E4F-84C3-0BD551CC7489}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9AB8491-BD4C-4E4F-84C3-0BD551CC7489}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9AB8491-BD4C-4E4F-84C3-0BD551CC7489}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9AB8491-BD4C-4E4F-84C3-0BD551CC7489}.Release|Any CPU.Build.0 = Release|Any CPU
{545DD6D4-9476-42D6-B51C-A28E000C489E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{545DD6D4-9476-42D6-B51C-A28E000C489E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{545DD6D4-9476-42D6-B51C-A28E000C489E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{545DD6D4-9476-42D6-B51C-A28E000C489E}.Release|Any CPU.Build.0 = Release|Any CPU
{9A04CB37-DA72-4008-9703-3AC5191974E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A04CB37-DA72-4008-9703-3AC5191974E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A04CB37-DA72-4008-9703-3AC5191974E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A04CB37-DA72-4008-9703-3AC5191974E9}.Release|Any CPU.Build.0 = Release|Any CPU
{95B7DD83-2C5A-4F1E-8EA7-39654B2B236A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95B7DD83-2C5A-4F1E-8EA7-39654B2B236A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95B7DD83-2C5A-4F1E-8EA7-39654B2B236A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95B7DD83-2C5A-4F1E-8EA7-39654B2B236A}.Release|Any CPU.Build.0 = Release|Any CPU
{34149709-F3ED-4FB5-A087-43EB195C948B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34149709-F3ED-4FB5-A087-43EB195C948B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34149709-F3ED-4FB5-A087-43EB195C948B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34149709-F3ED-4FB5-A087-43EB195C948B}.Release|Any CPU.Build.0 = Release|Any CPU
{2F1C0C8D-5C15-4BC0-811F-87F2C98D9790}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F1C0C8D-5C15-4BC0-811F-87F2C98D9790}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F1C0C8D-5C15-4BC0-811F-87F2C98D9790}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F1C0C8D-5C15-4BC0-811F-87F2C98D9790}.Release|Any CPU.Build.0 = Release|Any CPU
{31FA5B9B-4CD6-4BF3-B7A9-12C1E30DCAF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31FA5B9B-4CD6-4BF3-B7A9-12C1E30DCAF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31FA5B9B-4CD6-4BF3-B7A9-12C1E30DCAF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31FA5B9B-4CD6-4BF3-B7A9-12C1E30DCAF6}.Release|Any CPU.Build.0 = Release|Any CPU
{156B9B77-C2B7-4169-8FE7-1171D221446C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{156B9B77-C2B7-4169-8FE7-1171D221446C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{156B9B77-C2B7-4169-8FE7-1171D221446C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{156B9B77-C2B7-4169-8FE7-1171D221446C}.Release|Any CPU.Build.0 = Release|Any CPU
{0FFC557E-1B84-46A2-B6E8-06064FA7EA58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0FFC557E-1B84-46A2-B6E8-06064FA7EA58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0FFC557E-1B84-46A2-B6E8-06064FA7EA58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0FFC557E-1B84-46A2-B6E8-06064FA7EA58}.Release|Any CPU.Build.0 = Release|Any CPU
{AF32C621-30DC-40F5-8CE6-DD69053068E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF32C621-30DC-40F5-8CE6-DD69053068E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF32C621-30DC-40F5-8CE6-DD69053068E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF32C621-30DC-40F5-8CE6-DD69053068E9}.Release|Any CPU.Build.0 = Release|Any CPU
{55EEEBD2-CE45-45D6-9838-958F1C7354E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55EEEBD2-CE45-45D6-9838-958F1C7354E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55EEEBD2-CE45-45D6-9838-958F1C7354E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55EEEBD2-CE45-45D6-9838-958F1C7354E4}.Release|Any CPU.Build.0 = Release|Any CPU
{8A651E2D-A7C8-4EC7-B421-7A457654811D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A651E2D-A7C8-4EC7-B421-7A457654811D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A651E2D-A7C8-4EC7-B421-7A457654811D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A651E2D-A7C8-4EC7-B421-7A457654811D}.Release|Any CPU.Build.0 = Release|Any CPU
{5D20B150-C445-47BE-8CE8-C9F74F19A4F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D20B150-C445-47BE-8CE8-C9F74F19A4F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D20B150-C445-47BE-8CE8-C9F74F19A4F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D20B150-C445-47BE-8CE8-C9F74F19A4F2}.Release|Any CPU.Build.0 = Release|Any CPU
{0F5A1F4E-25FA-4D02-920D-CA2138498081}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F5A1F4E-25FA-4D02-920D-CA2138498081}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F5A1F4E-25FA-4D02-920D-CA2138498081}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F5A1F4E-25FA-4D02-920D-CA2138498081}.Release|Any CPU.Build.0 = Release|Any CPU
{6B594D23-B629-465C-B799-70EE9E56C218}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B594D23-B629-465C-B799-70EE9E56C218}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B594D23-B629-465C-B799-70EE9E56C218}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B594D23-B629-465C-B799-70EE9E56C218}.Release|Any CPU.Build.0 = Release|Any CPU
{4EB3DABC-D412-4C12-8876-41A1427A389E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4EB3DABC-D412-4C12-8876-41A1427A389E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4EB3DABC-D412-4C12-8876-41A1427A389E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4EB3DABC-D412-4C12-8876-41A1427A389E}.Release|Any CPU.Build.0 = Release|Any CPU
{5290E237-C2CD-48F2-99D2-817F9C2163C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5290E237-C2CD-48F2-99D2-817F9C2163C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5290E237-C2CD-48F2-99D2-817F9C2163C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5290E237-C2CD-48F2-99D2-817F9C2163C8}.Release|Any CPU.Build.0 = Release|Any CPU
{5A702CEE-DB36-4153-BD94-D8CF867E75A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A702CEE-DB36-4153-BD94-D8CF867E75A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A702CEE-DB36-4153-BD94-D8CF867E75A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A702CEE-DB36-4153-BD94-D8CF867E75A9}.Release|Any CPU.Build.0 = Release|Any CPU
{C1D4D665-23A3-4216-9CD1-D67AE9AAAA4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1D4D665-23A3-4216-9CD1-D67AE9AAAA4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1D4D665-23A3-4216-9CD1-D67AE9AAAA4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1D4D665-23A3-4216-9CD1-D67AE9AAAA4C}.Release|Any CPU.Build.0 = Release|Any CPU
{FE6FD36C-E171-4599-8D55-62DA579C0864}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE6FD36C-E171-4599-8D55-62DA579C0864}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE6FD36C-E171-4599-8D55-62DA579C0864}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE6FD36C-E171-4599-8D55-62DA579C0864}.Release|Any CPU.Build.0 = Release|Any CPU
{0364E724-1929-445E-9145-90A70B01DDC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0364E724-1929-445E-9145-90A70B01DDC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0364E724-1929-445E-9145-90A70B01DDC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0364E724-1929-445E-9145-90A70B01DDC0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{FC9B7611-836F-4127-8B44-A7C31F506807} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{F61679A9-E5DE-468A-B5A4-05F92D0143D2} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{19ECCE09-B5EB-406C-8C57-BAC66997D469} = {566EBBDA-19A4-4056-A615-D901D57D2439}
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{81765A64-3661-4E3E-B850-2F6F87A51F74} = {D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}
{BAE27510-8B5D-44B2-B33E-372A98908041} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{1BFAE226-8364-4086-825C-BB83F6F3EE4C} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{E7280DCA-7776-4A73-B9B5-41FD77FC8799} = {D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92} = {566EBBDA-19A4-4056-A615-D901D57D2439}
{C0270709-2A40-43B5-8CF1-69581B9FA2A1} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{FF2BF37C-E502-4C98-BEA0-701671DDFA08} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F} = {D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}
{17566860-3D98-4604-AA5B-47661F75609F} = {D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11} = {D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}
{2C838169-B187-4B09-8768-1C24C2521C8D} = {566EBBDA-19A4-4056-A615-D901D57D2439}
{E93F3DE2-FF3A-4709-96A3-8190AA14FA25} = {D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{5489181D-950C-44AF-873C-45EB0A3B6BD2} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{D9E4E686-423C-48EC-A392-404E7C00860C} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{4A010589-76E6-4F05-A5C4-4598D5DF11F8} = {D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}
{61C43D61-4368-4942-84A3-1EB623F4EF2A} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{6643A5AE-AB38-453F-ADCE-408E35A81A83} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{2CD5DBC3-3DA6-432D-BA97-F0B8D24501C2} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{32A74526-3E5F-413A-8CB4-1EFDAD4C8B91} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{851A1CB8-3CEB-41B4-956F-34D760D2A8E5} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{B93E3BF0-DAA7-49B7-B07D-0559C5816735} = {D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}
{4D1B198B-F773-44F2-872B-2B283053323C} = {D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B}
{E9AB8491-BD4C-4E4F-84C3-0BD551CC7489} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{545DD6D4-9476-42D6-B51C-A28E000C489E} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3} = {FA88A246-EF8E-46E3-90AF-539B8C0A6ADE}
{95B7DD83-2C5A-4F1E-8EA7-39654B2B236A} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{34149709-F3ED-4FB5-A087-43EB195C948B} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{2F1C0C8D-5C15-4BC0-811F-87F2C98D9790} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{31FA5B9B-4CD6-4BF3-B7A9-12C1E30DCAF6} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{156B9B77-C2B7-4169-8FE7-1171D221446C} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{0FFC557E-1B84-46A2-B6E8-06064FA7EA58} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{AF32C621-30DC-40F5-8CE6-DD69053068E9} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{55EEEBD2-CE45-45D6-9838-958F1C7354E4} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{8A651E2D-A7C8-4EC7-B421-7A457654811D} = {566EBBDA-19A4-4056-A615-D901D57D2439}
{5D20B150-C445-47BE-8CE8-C9F74F19A4F2} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{0F5A1F4E-25FA-4D02-920D-CA2138498081} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{6B594D23-B629-465C-B799-70EE9E56C218} = {E1A9B303-F281-45C5-A4F6-CADD9DE3F3C4}
{D19A38DD-68F1-4EF5-BF5F-8966CE0D9A5B} = {FA88A246-EF8E-46E3-90AF-539B8C0A6ADE}
{FE6FD36C-E171-4599-8D55-62DA579C0864} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
{0364E724-1929-445E-9145-90A70B01DDC0} = {6B46F6B1-1898-49B8-ADA7-5CAF68EB77E3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8B40BAFE-D862-4397-9495-8F5EAF5CE80C}
EndGlobalSection
@@ -346,8 +497,4 @@ Global
$5.EolMarker = Windows
$5.scope = text/plain
EndGlobalSection
GlobalSection(SubversionScc) = preSolution
Svn-Managed = True
Manager = AnkhSVN - Subversion Support for Visual Studio
EndGlobalSection
EndGlobal
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>Duplicati.CommandLine.AutoUpdater.Implementation</AssemblyName>
<RootNamespace>Duplicati.CommandLine.AutoUpdater</RootNamespace>
<Copyright>Copyright © 2024 Team Duplicati, MIT license</Copyright>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj" />
<ProjectReference Include="..\..\Library\Common\Duplicati.Library.Common.csproj" />
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
@@ -1,218 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E7280DCA-7776-4A73-B9B5-41FD77FC8799}</ProjectGuid>
<OutputType>Exe</OutputType>
<Prefer32Bit>False</Prefer32Bit>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.CommandLine.BackendTester</RootNamespace>
<AssemblyName>Duplicati.CommandLine.BackendTester</AssemblyName>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseMSBuildEngine>false</UseMSBuildEngine>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Commandlineparameters>~/.config/dupl-unittest.txt</Commandlineparameters>
<EnvironmentVariables>
<EnvironmentVariables>
<Variable name="AUTOUPDATER_Duplicati_SKIP_UPDATE" value="1" />
</EnvironmentVariables>
</EnvironmentVariables>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="NonSeekableStream.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Duplicati.snk" />
</ItemGroup>
<ItemGroup>
<None Include="app.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj">
<Project>{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}</Project>
<Name>Duplicati.Library.Backend.AzureBlob</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{b20a7cee-9c5b-47b9-8b76-bc85adfe8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
<Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
<Name>Duplicati.Library.Backend.Idrivee2</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
<Name>Duplicati.Library.Backend.Jottacloud</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Rclone\Duplicati.Library.Backend.Rclone.csproj">
<Project>{851a1cb8-3ceb-41b4-956f-34d760d2a8e5}</Project>
<Name>Duplicati.Library.Backend.Rclone</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
<Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
<Name>Duplicati.Library.Backend.Sia</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Storj\Duplicati.Library.Backend.Storj.csproj">
<Project>{ae035e01-c917-4f13-a35e-78f21c1a2f17}</Project>
<Name>Duplicati.Library.Backend.Storj</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Tardigrade\Duplicati.Library.Backend.Tardigrade.csproj">
<Project>{9a04cb37-da72-4008-9703-3ac5191974e9}</Project>
<Name>Duplicati.Library.Backend.Tardigrade</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\TencentCOS\Duplicati.Library.Backend.TencentCOS.csproj">
<Project>{545dd6d4-9476-42d6-b51c-a28e000c489e}</Project>
<Name>Duplicati.Library.Backend.TencentCOS</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj">
<Project>{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}</Project>
<Name>Duplicati.Library.DynamicLoader</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Interface\Duplicati.Library.Interface.csproj">
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
<Name>Duplicati.Library.Interface</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj">
<Project>{7E119745-1F62-43F0-936C-F312A1912C0B}</Project>
<Name>Duplicati.Library.AutoUpdater</Name>
</ProjectReference>
<ProjectReference Include="..\..\License\Duplicati.License.csproj">
<Project>{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}</Project>
<Name>Duplicati.License</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj">
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
<Name>Duplicati.Library.Backend.OneDrive</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj">
<Project>{C0270709-2A40-43B5-8CF1-69581B9FA2A1}</Project>
<Name>Duplicati.Library.Backend.TahoeLAFS</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\GoogleServices\Duplicati.Library.Backend.GoogleServices.csproj">
<Project>{5489181D-950C-44AF-873C-45EB0A3B6BD2}</Project>
<Name>Duplicati.Library.Backend.GoogleServices</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OpenStack\Duplicati.Library.Backend.OpenStack.csproj">
<Project>{D9E4E686-423C-48EC-A392-404E7C00860C}</Project>
<Name>Duplicati.Library.Backend.OpenStack</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj">
<Project>{1BFAE226-8364-4086-825C-BB83F6F3EE4C}</Project>
<Name>Duplicati.Library.Backend.CloudFiles</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\File\Duplicati.Library.Backend.File.csproj">
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
<Name>Duplicati.Library.Backend.File</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj">
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj">
<Project>{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}</Project>
<Name>Duplicati.Library.Backend.S3</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
<Project>{FF2BF37C-E502-4C98-BEA0-701671DDFA08}</Project>
<Name>Duplicati.Library.Backend.SSHv2</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj">
<Project>{BAE27510-8B5D-44B2-B33E-372A98908041}</Project>
<Name>Duplicati.Library.Backend.WEBDAV</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj">
<Project>{52826615-7964-47FE-B4B3-1B2DBDF605B9}</Project>
<Name>Duplicati.Library.Modules.Builtin</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj">
<Project>{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}</Project>
<Name>Duplicati.Library.OAuthHelper</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Localization\Duplicati.Library.Localization.csproj">
<Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
<Name>Duplicati.Library.Localization</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Logging\Duplicati.Library.Logging.csproj">
<Project>{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}</Project>
<Name>Duplicati.Library.Logging</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Backblaze\Duplicati.Library.Backend.Backblaze.csproj">
<Project>{61C43D61-4368-4942-84A3-1EB623F4EF2A}</Project>
<Name>Duplicati.Library.Backend.Backblaze</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Mega\Duplicati.Library.Backend.Mega.csproj">
<Project>{6643A5AE-AB38-453F-ADCE-408E35A81A83}</Project>
<Name>Duplicati.Library.Backend.Mega</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Box\Duplicati.Library.Backend.Box.csproj">
<Project>{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}</Project>
<Name>Duplicati.Library.Backend.Box</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj">
<Project>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</Project>
<Name>Duplicati.Library.Backend.AlternativeFTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Common\Duplicati.Library.Common.csproj">
<Project>{D63E53E4-A458-4C2F-914D-92F715F58ACF}</Project>
<Name>Duplicati.Library.Common</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Compression\Duplicati.Library.Compression.csproj">
<Project>{19ECCE09-B5EB-406C-8C57-BAC66997D469}</Project>
<Name>Duplicati.Library.Compression</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\SQLiteHelper\Duplicati.Library.SQLiteHelper.csproj">
<Project>{2C838169-B187-4B09-8768-1C24C2521C8D}</Project>
<Name>Duplicati.Library.SQLiteHelper</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Description>A backend debugging tool for Duplicati</Description>
<AssemblyName>Duplicati.CommandLine.BackendTester.Implementation</AssemblyName>
<Copyright>Copyright © 2024 Team Duplicati, MIT license</Copyright>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj" />
<ProjectReference Include="..\..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj" />
<ProjectReference Include="..\..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj" />
<ProjectReference Include="..\..\License\Duplicati.License.csproj" />
<ProjectReference Include="..\..\Library\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj" />
<ProjectReference Include="..\..\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj" />
<ProjectReference Include="..\..\Library\Localization\Duplicati.Library.Localization.csproj" />
<ProjectReference Include="..\..\Library\Logging\Duplicati.Library.Logging.csproj" />
<ProjectReference Include="..\..\Library\Common\Duplicati.Library.Common.csproj" />
<ProjectReference Include="..\..\Library\SQLiteHelper\Duplicati.Library.SQLiteHelper.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
Binary file not shown.
+27 -31
View File
@@ -1,23 +1,23 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
@@ -29,9 +29,8 @@ using System.Threading;
namespace Duplicati.CommandLine.BackendTester
{
class Program
public class Program
{
/// <summary>
/// Used to maintain a reference to initialized system settings.
/// </summary>
@@ -63,13 +62,7 @@ namespace Duplicati.CommandLine.BackendTester
/// The main entry point for the application.
/// </summary>
[STAThread]
public static int Main(string[] args)
{
Duplicati.Library.AutoUpdater.UpdaterManager.IgnoreWebrootFolder = true;
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args);
}
public static void RealMain(string[] _args)
public static int Main(string[] _args)
{
try
{
@@ -107,7 +100,7 @@ namespace Duplicati.CommandLine.BackendTester
foreach (string s in lines)
Console.WriteLine(s);
return;
return 0;
}
if (options.ContainsKey("tempdir") && !string.IsNullOrEmpty(options["tempdir"]))
@@ -129,14 +122,17 @@ namespace Duplicati.CommandLine.BackendTester
{
Console.WriteLine("Starting run no {0}", i);
if (!Run(args, options, i == 0))
return;
return 1;
}
Console.WriteLine("Unittest complete!");
return 0;
}
catch (Exception ex)
{
Console.WriteLine("Unittest failed: " + ex);
}
return 1;
}
static bool Run(List<string> args, Dictionary<string, string> options, bool first)
@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CommandLine.BackendTester")]
[assembly: AssemblyDescription("A backend debugging tool for Duplicati")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Duplicati Team")]
[assembly: AssemblyProduct("CommandLine.BackendTester")]
[assembly: AssemblyCopyright("Copyright © Duplicati Team 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("53df9eb0-a6e8-49a2-838d-b2a2c4a8d41f")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("2.0.0.7")]
[assembly: AssemblyVersion("2.0.0.7")]
[assembly: AssemblyFileVersion("2.0.0.7")]
@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />
</startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.4.0" newVersion="3.0.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.3" newVersion="4.2.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -1,171 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}</ProjectGuid>
<OutputType>Exe</OutputType>
<Prefer32Bit>False</Prefer32Bit>
<RootNamespace>Duplicati.CommandLine.BackendTool</RootNamespace>
<AssemblyName>Duplicati.CommandLine.BackendTool</AssemblyName>
<AssemblyOriginatorKeyFile>..\Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseMSBuildEngine>false</UseMSBuildEngine>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<Prefer32Bit>false</Prefer32Bit>
<EnvironmentVariables>
<EnvironmentVariables>
<Variable name="AUTOUPDATER_Duplicati_SKIP_UPDATE" value="1" />
</EnvironmentVariables>
</EnvironmentVariables>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\..\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj">
<Project>{1BFAE226-8364-4086-825C-BB83F6F3EE4C}</Project>
<Name>Duplicati.Library.Backend.CloudFiles</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj">
<Project>{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}</Project>
<Name>Duplicati.Library.Backend.AzureBlob</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\File\Duplicati.Library.Backend.File.csproj">
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
<Name>Duplicati.Library.Backend.File</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj">
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
<Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
<Name>Duplicati.Library.Backend.Idrivee2</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
<Name>Duplicati.Library.Backend.Jottacloud</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Rclone\Duplicati.Library.Backend.Rclone.csproj">
<Project>{851a1cb8-3ceb-41b4-956f-34d760d2a8e5}</Project>
<Name>Duplicati.Library.Backend.Rclone</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj">
<Project>{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}</Project>
<Name>Duplicati.Library.Backend.S3</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
<Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
<Name>Duplicati.Library.Backend.Sia</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
<Project>{FF2BF37C-E502-4C98-BEA0-701671DDFA08}</Project>
<Name>Duplicati.Library.Backend.SSHv2</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj">
<Project>{C0270709-2A40-43B5-8CF1-69581B9FA2A1}</Project>
<Name>Duplicati.Library.Backend.TahoeLAFS</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Storj\Duplicati.Library.Backend.Storj.csproj">
<Project>{ae035e01-c917-4f13-a35e-78f21c1a2f17}</Project>
<Name>Duplicati.Library.Backend.Storj</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Tardigrade\Duplicati.Library.Backend.Tardigrade.csproj">
<Project>{9a04cb37-da72-4008-9703-3ac5191974e9}</Project>
<Name>Duplicati.Library.Backend.Tardigrade</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\TencentCOS\Duplicati.Library.Backend.TencentCOS.csproj">
<Project>{545dd6d4-9476-42d6-b51c-a28e000c489e}</Project>
<Name>Duplicati.Library.Backend.TencentCOS</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj">
<Project>{BAE27510-8B5D-44B2-B33E-372A98908041}</Project>
<Name>Duplicati.Library.Backend.WEBDAV</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj">
<Project>{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}</Project>
<Name>Duplicati.Library.DynamicLoader</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Interface\Duplicati.Library.Interface.csproj">
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
<Name>Duplicati.Library.Interface</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj">
<Project>{7E119745-1F62-43F0-936C-F312A1912C0B}</Project>
<Name>Duplicati.Library.AutoUpdater</Name>
</ProjectReference>
<ProjectReference Include="..\..\License\Duplicati.License.csproj">
<Project>{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}</Project>
<Name>Duplicati.License</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj">
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
<Name>Duplicati.Library.Backend.OneDrive</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\GoogleServices\Duplicati.Library.Backend.GoogleServices.csproj">
<Project>{5489181D-950C-44AF-873C-45EB0A3B6BD2}</Project>
<Name>Duplicati.Library.Backend.GoogleServices</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OpenStack\Duplicati.Library.Backend.OpenStack.csproj">
<Project>{D9E4E686-423C-48EC-A392-404E7C00860C}</Project>
<Name>Duplicati.Library.Backend.OpenStack</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Backblaze\Duplicati.Library.Backend.Backblaze.csproj">
<Project>{61C43D61-4368-4942-84A3-1EB623F4EF2A}</Project>
<Name>Duplicati.Library.Backend.Backblaze</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Mega\Duplicati.Library.Backend.Mega.csproj">
<Project>{6643A5AE-AB38-453F-ADCE-408E35A81A83}</Project>
<Name>Duplicati.Library.Backend.Mega</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Box\Duplicati.Library.Backend.Box.csproj">
<Project>{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}</Project>
<Name>Duplicati.Library.Backend.Box</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj">
<Project>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</Project>
<Name>Duplicati.Library.Backend.AlternativeFTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>Duplicati.CommandLine.BackendTool.Implementation</AssemblyName>
<Copyright>Copyright © 2024 Team Duplicati, MIT license</Copyright>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj" />
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj" />
<ProjectReference Include="..\..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj" />
<ProjectReference Include="..\..\License\Duplicati.License.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
+1 -7
View File
@@ -34,13 +34,7 @@ namespace Duplicati.CommandLine.BackendTool
/// The main entry point for the application.
/// </summary>
[STAThread]
public static int Main(string[] args)
{
Duplicati.Library.AutoUpdater.UpdaterManager.IgnoreWebrootFolder = true;
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args);
}
public static int RealMain(string[] _args)
public static int Main(string[] _args)
{
bool debugoutput = false;
try
@@ -1,27 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("Duplicati.CommandLine.BackendTool")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("2.0.0.7")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]
@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />
</startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.3" newVersion="4.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.4.0" newVersion="3.0.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -24,6 +24,8 @@ using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Duplicati.Library.Common.IO;
using Duplicati.Library.Utility;
@@ -38,8 +40,9 @@ namespace Duplicati.CommandLine
private readonly System.Threading.ManualResetEvent m_readyEvent;
private readonly System.Threading.ManualResetEvent m_finishEvent;
private readonly ConsoleOutput m_output;
private System.Threading.Thread m_thread;
private readonly TimeSpan m_updateFrequency;
private Task m_task;
private readonly CancellationTokenSource m_cancellationTokenSource;
public PeriodicOutput(ConsoleOutput messageSink, TimeSpan updateFrequency)
{
@@ -47,10 +50,8 @@ namespace Duplicati.CommandLine
m_readyEvent = new System.Threading.ManualResetEvent(false);
m_finishEvent = new System.Threading.ManualResetEvent(false);
m_updateFrequency = updateFrequency;
m_thread = new System.Threading.Thread(this.ThreadMain);
m_thread.IsBackground = true;
m_thread.Name = "Periodic console writer";
m_thread.Start();
m_cancellationTokenSource = new CancellationTokenSource();
m_task = Task.Run(() => this.ThreadMain(m_cancellationTokenSource.Token), m_cancellationTokenSource.Token);
}
public void SetReady() { m_readyEvent.Set(); }
@@ -58,13 +59,13 @@ namespace Duplicati.CommandLine
public bool Join(TimeSpan wait)
{
if (m_thread != null)
return m_thread.Join(wait);
if (m_task != null)
return this.m_task.Wait(wait);
return true;
}
private void ThreadMain()
private void ThreadMain(CancellationToken cancellationToken)
{
m_readyEvent.WaitOne();
if (m_finishEvent.WaitOne(TimeSpan.FromMilliseconds(10), true))
@@ -73,7 +74,7 @@ namespace Duplicati.CommandLine
var last_count = -1L;
var finished = false;
while (true)
while (!cancellationToken.IsCancellationRequested)
{
float progress;
long filesprocessed;
@@ -110,22 +111,22 @@ namespace Duplicati.CommandLine
public void Dispose()
{
if (m_thread != null)
if (m_task != null)
{
try
{
m_finishEvent.Set();
m_readyEvent.Set();
if (m_thread != null && m_thread.IsAlive)
if (m_task != null)
{
m_thread.Abort();
m_thread.Join(500);
m_cancellationTokenSource.Cancel();
m_task.Wait(500);
}
}
finally
{
m_thread = null;
m_task = null;
}
}
}
@@ -133,13 +134,15 @@ namespace Duplicati.CommandLine
public static int Examples(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
Duplicati.CommandLine.Help.PrintUsage(outwriter, "example", options);
using (new Duplicati.Library.Main.LocaleChange(options))
Duplicati.CommandLine.Help.PrintUsage(outwriter, "example", options);
return 0;
}
public static int Help(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
Duplicati.CommandLine.Help.PrintUsage(outwriter, args.Count > 1? args[1] : "help", options);
using (new Duplicati.Library.Main.LocaleChange(options))
Duplicati.CommandLine.Help.PrintUsage(outwriter, args.Count > 1 ? args[1] : "help", options);
return 0;
}
@@ -174,8 +177,8 @@ namespace Duplicati.CommandLine
options["no-encryption"] = "true";
}
using(var console = new ConsoleOutput(outwriter, options))
using(var i = new Library.Main.Controller(backend, options, console))
using (var console = new ConsoleOutput(outwriter, options))
using (var i = new Library.Main.Controller(backend, options, console))
{
setup(i);
i.ListAffected(args, res =>
@@ -258,7 +261,7 @@ namespace Duplicati.CommandLine
if (!containsSeparators && arg.StartsWith("@", StringComparison.Ordinal))
{
// Convert to Regexp filter and prefix with ".*/"
return $"[.*{Utility.ConvertLiteralToRegExp(Util.DirectorySeparatorString + arg.Substring(1))}]";
return $"[.*{Library.Utility.Utility.ConvertLiteralToRegExp(Util.DirectorySeparatorString + arg.Substring(1))}]";
}
else if (!containsSeparators && !containsWildcards && !arg.StartsWith("[", StringComparison.Ordinal))
{
@@ -289,7 +292,7 @@ namespace Duplicati.CommandLine
if (endsWithSeparator && arg.StartsWith("@", StringComparison.Ordinal))
{
// Convert to Regexp filter and suffix with ".*"
return $"[{Utility.ConvertLiteralToRegExp(arg.Substring(1))}.*]";
return $"[{Library.Utility.Utility.ConvertLiteralToRegExp(arg.Substring(1))}.*]";
}
else if (endsWithSeparator && !containsWildcards && !arg.StartsWith("[", StringComparison.Ordinal))
{
@@ -323,7 +326,7 @@ namespace Duplicati.CommandLine
filter = new Duplicati.Library.Utility.FilterExpression();
using (var console = new ConsoleOutput(outwriter, options))
using(var i = new Library.Main.Controller(args[0], options, console))
using (var i = new Library.Main.Controller(args[0], options, console))
{
setup(i);
var backend = args[0];
@@ -411,7 +414,7 @@ namespace Duplicati.CommandLine
{
outwriter.WriteLine("Listing filesets:");
foreach(var e in res.Filesets)
foreach (var e in res.Filesets)
{
if (e.FileCount >= 0)
outwriter.WriteLine("{0}\t: {1} ({2} files, {3})", e.Version, e.Time, e.FileCount, Library.Utility.Utility.FormatSizeString(e.FileSizes));
@@ -443,10 +446,10 @@ namespace Duplicati.CommandLine
else
{
outwriter.WriteLine("Listing files and versions:");
foreach(var e in res.Files)
foreach (var e in res.Files)
{
outwriter.WriteLine(e.Path);
foreach(var nx in res.Filesets.Zip(e.Sizes, (a, b) => new { Index = a.Version, Time = a.Time, Size = b } ))
foreach (var nx in res.Filesets.Zip(e.Sizes, (a, b) => new { Index = a.Version, Time = a.Time, Size = b }))
outwriter.WriteLine("{0}\t: {1} {2}", nx.Index, nx.Time, nx.Size < 0 ? " - " : Library.Utility.Utility.FormatSizeString(nx.Size));
outwriter.WriteLine();
@@ -470,7 +473,7 @@ namespace Duplicati.CommandLine
}
using (var console = new ConsoleOutput(outwriter, options))
using(var i = new Library.Main.Controller(args[0], options, console))
using (var i = new Library.Main.Controller(args[0], options, console))
{
setup(i);
args.RemoveAt(0);
@@ -487,7 +490,7 @@ namespace Duplicati.CommandLine
else
outwriter.WriteLine(Strings.Program.DeletedBackups);
foreach(var f in res.DeletedSets)
foreach (var f in res.DeletedSets)
outwriter.WriteLine("{0}: {1}", f.Item1, f.Item2);
}
}
@@ -524,7 +527,7 @@ namespace Duplicati.CommandLine
args = SuffixArgsWithAsterisk(PrefixArgsWithAsterisk(args)).ToList();
using(var output = new ConsoleOutput(outwriter, options))
using (var output = new ConsoleOutput(outwriter, options))
using (var i = new Library.Main.Controller(backend, options, output))
{
output.MessageEvent(string.Format("Restore started at {0}", DateTime.Now));
@@ -716,7 +719,7 @@ namespace Duplicati.CommandLine
if (args.Count != 1)
return PrintWrongNumberOfArguments(outwriter, args, 1);
using(var console = new ConsoleOutput(outwriter, options))
using (var console = new ConsoleOutput(outwriter, options))
using (var i = new Library.Main.Controller(args[0], options, console))
{
setup(i);
@@ -765,7 +768,7 @@ namespace Duplicati.CommandLine
}
else
{
foreach(var n in result.Verifications)
foreach (var n in result.Verifications)
{
var changecount = n.Value.Count();
if (changecount == 0)
@@ -1000,7 +1003,7 @@ namespace Duplicati.CommandLine
}
using (var console = new ConsoleOutput(outwriter, options))
using(var i = new Library.Main.Controller("dummy://", options, console))
using (var i = new Library.Main.Controller("dummy://", options, console))
{
setup(i);
var result = i.TestFilter(args.ToArray(), filter);
@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Description>A commandline version of Duplicati</Description>
<AssemblyName>Duplicati.CommandLine.Implementation</AssemblyName>
<ApplicationIcon>TrayWarning.ico</ApplicationIcon>
<Copyright>Copyright © 2024 Team Duplicati, MIT license</Copyright>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj" />
<ProjectReference Include="..\..\Library\Common\Duplicati.Library.Common.csproj" />
<ProjectReference Include="..\..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj" />
<ProjectReference Include="..\..\Library\Logging\Duplicati.Library.Logging.csproj" />
<ProjectReference Include="..\..\Library\Main\Duplicati.Library.Main.csproj" />
<ProjectReference Include="..\..\License\Duplicati.License.csproj" />
<ProjectReference Include="..\BackendTool\Duplicati.CommandLine.BackendTool.csproj" />
<ProjectReference Include="..\BackendTester\Duplicati.CommandLine.BackendTester.csproj" />
<ProjectReference Include="..\..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj" />
<ProjectReference Include="..\..\Library\Localization\Duplicati.Library.Localization.csproj" />
<ProjectReference Include="..\RecoveryTool\Duplicati.CommandLine.RecoveryTool.csproj" />
<ProjectReference Include="..\..\Library\UsageReporter\Duplicati.Library.UsageReporter.csproj" />
<ProjectReference Include="..\..\Tools\Duplicati.Tools.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="help.txt" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
@@ -24,6 +24,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Duplicati.Library.AutoUpdater;
using Duplicati.Library.Common;
using FilterGroup = Duplicati.Library.Utility.FilterGroup;
@@ -32,18 +33,17 @@ namespace Duplicati.CommandLine
public static class Help
{
private static readonly Dictionary<string, string> _document;
private const string RESOURCE_NAME = "Duplicati.CommandLine.help.txt";
private const string RESOURCE_NAME = "help.txt";
private static readonly System.Text.RegularExpressions.Regex NAMEDOPTION_REGEX = new System.Text.RegularExpressions.Regex("\\%OPTION\\:(?<name>[^\\%]+)\\%");
static Help()
{
_document = new Dictionary<string,string>(StringComparer.OrdinalIgnoreCase);
using (System.IO.StreamReader sr = new System.IO.StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(RESOURCE_NAME)))
_document = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
using (var sr = new StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(typeof(Help), RESOURCE_NAME)))
{
List<string> keywords = new List<string>();
StringBuilder sb = new StringBuilder();
foreach(var line in sr.ReadToEnd().Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.None))
foreach (var line in sr.ReadToEnd().Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.None))
{
if (line.Trim().StartsWith("#", StringComparison.Ordinal))
continue;
@@ -53,14 +53,14 @@ namespace Duplicati.CommandLine
if (sb.Length > 0)
{
string s = sb.ToString();
foreach(var k in keywords)
foreach (var k in keywords)
_document[k] = s;
keywords.Clear();
sb.Clear();
}
string[] elems = line.Split(new string[] {" ", "\t"}, StringSplitOptions.RemoveEmptyEntries);
string[] elems = line.Split(new string[] { " ", "\t" }, StringSplitOptions.RemoveEmptyEntries);
if (elems.Length >= 2 && string.Equals(elems[elems.Length - 2], "help", StringComparison.OrdinalIgnoreCase))
keywords.Add(elems[elems.Length - 1]);
else if (elems.Length == 3 && string.Equals(elems[elems.Length - 1], "help", StringComparison.OrdinalIgnoreCase))
@@ -75,7 +75,7 @@ namespace Duplicati.CommandLine
if (sb.Length > 0)
{
string s = sb.ToString();
foreach(var k in keywords)
foreach (var k in keywords)
_document[k] = s;
}
}
@@ -115,14 +115,14 @@ namespace Duplicati.CommandLine
string tp = _document[topic];
Library.Main.Options opts = new Library.Main.Options(new Dictionary<string, string>());
tp = tp.Replace("%CLI_EXE%", PackageHelper.GetExecutableName(PackageHelper.NamedExecutable.CommandLine));
tp = tp.Replace("%VERSION%", License.VersionNumbers.Version);
tp = tp.Replace("%BACKENDS%", string.Join(", ", Library.DynamicLoader.BackendLoader.Keys));
tp = tp.Replace("%MONO%", Library.Utility.Utility.IsMono ? "mono " : "");
tp = tp.Replace("%APP_PATH%", System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location));
tp = tp.Replace("%APP_PATH%", Path.Combine(UpdaterManager.INSTALLATIONDIR, PackageHelper.GetExecutableName(PackageHelper.NamedExecutable.CommandLine)));
tp = tp.Replace("%PATH_SEPARATOR%", System.IO.Path.PathSeparator.ToString());
tp = tp.Replace("%EXAMPLE_SOURCE_PATH%", Platform.IsClientPosix ? "/source" : @"D:\source");
tp = tp.Replace("%EXAMPLE_SOURCE_FILE%", Platform.IsClientPosix ? "/source/myfile.txt" : @"D:\source\file.txt");
tp = tp.Replace("%EXAMPLE_RESTORE_PATH%", Platform.IsClientPosix ? "/restore" : @"D:\restore");
tp = tp.Replace("%EXAMPLE_SOURCE_PATH%", !OperatingSystem.IsWindows() ? "/source" : @"D:\source");
tp = tp.Replace("%EXAMPLE_SOURCE_FILE%", !OperatingSystem.IsWindows() ? "/source/myfile.txt" : @"D:\source\file.txt");
tp = tp.Replace("%EXAMPLE_RESTORE_PATH%", !OperatingSystem.IsWindows() ? "/restore" : @"D:\restore");
tp = tp.Replace("%ENCRYPTIONMODULES%", string.Join(", ", Library.DynamicLoader.EncryptionLoader.Keys));
tp = tp.Replace("%COMPRESSIONMODULES%", string.Join(", ", Library.DynamicLoader.CompressionLoader.Keys));
tp = tp.Replace("%DEFAULTENCRYPTIONMODULE%", opts.EncryptionModule);
@@ -132,7 +132,7 @@ namespace Duplicati.CommandLine
tp = tp.Replace("%FILTER_GROUPS_SHORT%", string.Join(Environment.NewLine + " ", metaGroupNames.Concat(Enum.GetNames(typeof(FilterGroup)).Except(metaGroupNames, StringComparer.OrdinalIgnoreCase).OrderBy(x => x, StringComparer.OrdinalIgnoreCase)).Select(group => "{" + group + "}")));
tp = tp.Replace("%FILTER_GROUPS_LONG%", Library.Utility.FilterGroups.GetOptionDescriptions(4, true));
if (Platform.IsClientWindows)
if (OperatingSystem.IsWindows())
{
// These properties are only valid for Windows
tp = tp.Replace("%EXAMPLE_WILDCARD_DRIVE_SOURCE_PATH%", @"*:\source");
@@ -205,7 +205,7 @@ namespace Duplicati.CommandLine
tp = tp.Replace("%ALLOPTIONS%", string.Join(Environment.NewLine, lines.ToArray()));
}
if (tp.Contains("%MODULEOPTIONS%"))
{
//Figure out which module we are in
@@ -261,7 +261,7 @@ namespace Duplicati.CommandLine
}
if (NAMEDOPTION_REGEX.IsMatch(tp))
tp = NAMEDOPTION_REGEX.Replace(tp, new Matcher().MathEvaluator);
tp = NAMEDOPTION_REGEX.Replace(tp, new Matcher().MathEvaluator);
PrintFormatted(outwriter, tp.Split(new string[] { Environment.NewLine }, StringSplitOptions.None));
}
@@ -398,15 +398,15 @@ namespace Duplicati.CommandLine
private static void PrintFormatted(TextWriter outwriter, IEnumerable<string> lines)
{
int windowWidth = 80;
try
try
{
// This can go wrong if we have no attached console
if (outwriter == Console.Out)
windowWidth = Math.Max(12, Console.WindowWidth == 0 ? 80 : Console.WindowWidth);
windowWidth = Math.Max(12, Console.WindowWidth == 0 ? 80 : Console.WindowWidth);
}
catch { }
foreach (string s in lines)
{
if (string.IsNullOrEmpty(s) || s.Trim().Length == 0)
@@ -472,7 +472,7 @@ namespace Duplicati.CommandLine
foreach (Duplicati.Library.Interface.IGenericModule mod in Library.DynamicLoader.GenericLoader.Modules)
if (mod.SupportedCommands != null)
foundArgs.Add(mod.SupportedCommands);
foreach (IEnumerable<Library.Interface.ICommandLineArgument> arglst in foundArgs)
if (arglst != null)
{
@@ -510,7 +510,7 @@ namespace Duplicati.CommandLine
return "";
List<string> lines = new List<string>();
foreach(Duplicati.Library.Interface.ICommandLineArgument arg in args)
foreach (Duplicati.Library.Interface.ICommandLineArgument arg in args)
if (!arg.Deprecated)
lines.Add(PrintArgSimple(arg, arg.Name));
@@ -1,23 +1,23 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
@@ -25,7 +25,7 @@ using System.Linq;
using Duplicati.Library.Localization.Short;
using System.IO;
using Duplicati.Library.Interface;
using Duplicati.Library.Logging;
using Duplicati.Library.AutoUpdater;
namespace Duplicati.CommandLine
{
@@ -38,14 +38,7 @@ namespace Duplicati.CommandLine
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static int Main(string[] args)
{
Duplicati.Library.AutoUpdater.UpdaterManager.IgnoreWebrootFolder = true;
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args);
}
public static int RealMain(string[] args)
{
Library.UsageReporter.Reporter.Initialize();
FROM_COMMANDLINE = true;
@@ -101,7 +94,7 @@ namespace Duplicati.CommandLine
private static int ShowChangeLog(TextWriter outwriter)
{
var path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "changelog.txt");
var path = System.IO.Path.Combine(UpdaterManager.INSTALLATIONDIR, "changelog.txt");
outwriter.WriteLine(System.IO.File.ReadAllText(path));
return 0;
}
@@ -114,18 +107,28 @@ namespace Duplicati.CommandLine
if (update != null && update.Version != Library.AutoUpdater.UpdaterManager.SelfVersion.Version)
{
outwriter.WriteLine("Found update \"{0}\", downloading ...", update.Displayname);
long lastpg = 0;
Library.AutoUpdater.UpdaterManager.DownloadAndUnpackUpdate(update, f =>
var package = update.FindPackage();
if (package == null)
{
var npg = (long)(f * 100);
if (Math.Abs(npg - lastpg) >= 5 || (npg == 100 && lastpg != 100))
outwriter.WriteLine($"Failed to locate a matching package for this machine, please visit this link and select the correct package: {update.GetGenericUpdatePageUrl()}");
}
else
{
var filename = Path.GetFullPath(package.GetFilename());
outwriter.WriteLine("Downloading update \"{0}\" to {1} ...", update.Displayname, filename);
long lastpg = 0;
Library.AutoUpdater.UpdaterManager.DownloadUpdate(update, package, filename, f =>
{
lastpg = npg;
outwriter.WriteLine("Downloading {0}% ...", npg);
}
});
outwriter.WriteLine("Update \"{0}\" ({1}) installed, using on next launch", update.Displayname, update.Version);
var npg = (long)(f * 100);
if (Math.Abs(npg - lastpg) >= 5 || (npg == 100 && lastpg != 100))
{
lastpg = npg;
outwriter.WriteLine("Downloading {0}% ...", npg);
}
});
outwriter.WriteLine("Update \"{0}\" ({1}) downloaded", update.Displayname, update.Version);
}
}
}
@@ -20,8 +20,10 @@
// DEALINGS IN THE SOFTWARE.
using Duplicati.Library.Localization.Short;
namespace Duplicati.CommandLine.Strings {
internal static class Program {
namespace Duplicati.CommandLine.Strings
{
internal static class Program
{
public static string DeleteCommandNeedsOptions(string commandname, string[] options) { return LC.L(@"The command {0} needs at least one of the following options set: {1}", commandname, string.Join(", ", options)); }
public static string WrongNumberOfCommandsError_v2(int actualcommands, int expectedcommands, string[] commands) { return LC.L(@"Found {0} commands but expected {1}, commands:
{2}", actualcommands, expectedcommands, string.Join(System.Environment.NewLine, commands ?? new string[0])); }
@@ -47,13 +49,12 @@ namespace Duplicati.CommandLine.Strings {
public static string IncludeShort { get { return LC.L(@"Include files"); } }
public static string ExcludeLong { get { return LC.L(@"Exclude files that match this filter. The special character * means any number of character, and the special character ? means any single character, use *.txt to exclude all files with a txt extension. Regular expressions are also supported and can be supplied by using hard braces, i.e. [.*\.txt]. Filter groups (which encapsulate a built-in set of well-known files and folders) can be specified by using curly braces, i.e. {{TemporaryFiles}}."); } }
public static string ExcludeShort { get { return LC.L(@"Exclude files"); } }
public static string ControlFilesOptionShort { get { return LC.L(@"If this option is used with a backup operation, it is interpreted as a list of files to add to the filesets. When used with list or restore, it will list or restore the control files instead of the normal files."); } }
public static string ControlFilesOptionLong { get { return LC.L(@"Use control files"); } }
public static string ControlFilesOptionShort { get { return LC.L(@"Use control files"); } }
public static string ControlFilesOptionLong { get { return LC.L(@"If this option is used with a backup operation, it is interpreted as a list of files to add to the filesets. When used with list or restore, it will list or restore the control files instead of the normal files."); } }
public static string QuietConsoleOptionLong { get { return LC.L(@"If this option is set, progress reports and other messages that would normally go to the console will be redirected to the log."); } }
public static string QuietConsoleOptionShort { get { return LC.L(@"Disable console output"); } }
public static string SkippingSourceArgumentsOnNonBackupOperation { get { return @"The --source argument was specified in the parameter file, but the current operation is not a backup operation, so the argument is ignored"; } }
// ReSharper disable once UnusedMember.Global
// This is a placeholder message that is intended to be used with the code
// for each error and log message. The idea is that the commandline will

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

@@ -9,17 +9,17 @@
> duplicati.commandline.exe
> duplicati.commandline.exe help
See duplicati.commandline.exe help <topic> for more information.
See %CLI_EXE% help <topic> for more information.
General: example, changelog
Commands: backup, find, restore, delete, compact, test, compare, purge, vacuum
Repair: repair, affected, list-broken-files, purge-broken-files
Debug: debug, logging, create-report, test-filters, system-info, send-mail
Targets: %BACKENDS%
Modules: %ENCRYPTIONMODULES%, %COMPRESSIONMODULES%, %GENERICMODULES%
Formats: date, time, size, encryption, compression
Formats: date, time, size, decimal, encryption, compression
Advanced: mail, advanced, returncodes, filter, filter-groups, <option>
http://www.duplicati.com/ Version: %VERSION%
https://duplicati.com/ Version: %VERSION%
@@ -30,7 +30,7 @@ Show the last changes to Duplicati
==================================
Duplicati updates automatically when a newer version is available. The following command will show a list of versions and changes.
%MONO%"%APP_PATH%" changelog
"%APP_PATH%" changelog
# =============================================================================
> duplicati.commandline.exe help system-info
@@ -40,7 +40,7 @@ Show system information as seen by Duplicati
============================================
Issue the following command to see a variety of system information relevant to Duplicati.
%MONO%"%APP_PATH%" system-info
"%APP_PATH%" system-info
# =============================================================================
> duplicati.commandline.exe help example
@@ -50,25 +50,25 @@ Make an encrypted backup
========================
The following command will make an encrypted backup and store it on an FTP server. As no passphrase is specified, the user is prompted for a password. The upload speed is throttled to 500kB/s. Backups older than one month are considered old. Old backups are deleted automatically. The maximum file size is limited to 50MB (default).
%MONO%"%APP_PATH%" backup ftp://me:example.com@ftp.example.com/target "%EXAMPLE_SOURCE_PATH%" --throttle=500kB
"%APP_PATH%" backup ftp://me:example.com@ftp.example.com/target "%EXAMPLE_SOURCE_PATH%" --throttle=500kB
Search for files in a backup
============================
The backup can be searched for specific files. The following command returns all files "%EXAMPLE_SOURCE_FILE%" of the last backup. File names can also contain the wildcards * and ?.
%MONO%"%APP_PATH%" find ftp://me:example.com@ftp.example.com/target "%EXAMPLE_SOURCE_FILE%"
"%APP_PATH%" find ftp://me:example.com@ftp.example.com/target "%EXAMPLE_SOURCE_FILE%"
Restore a specific file
=======================
The following command will restore "%EXAMPLE_SOURCE_FILE%" from the backup in the latest version to its original destination and overwrite an existing file.
%MONO%"%APP_PATH%" restore ftp://me:example.com@ftp.example.com/target "%EXAMPLE_SOURCE_FILE%" --overwrite
"%APP_PATH%" restore ftp://me:example.com@ftp.example.com/target "%EXAMPLE_SOURCE_FILE%" --overwrite
# =============================================================================
> duplicati.commandline.exe help backup
Usage: backup <storage-URL> "<source-path>" [<options>]
Usage: %CLI_EXE% backup <storage-URL> "<source-path>" [<options>]
Makes a backup of <source-path> and stores it in <storage-URL>. The format for <storage-URL> is
protocol://username:password@hostname:port/path?backend_option1=value1&backend_option2=value2.
@@ -97,7 +97,7 @@ Usage: backup <storage-URL> "<source-path>" [<options>]
> duplicati.commandline.exe help find
> duplicati.commandline.exe help list
Usage: find <storage-URL> ["<filename>"] [<options>]
Usage: %CLI_EXE% find <storage-URL> ["<filename>"] [<options>]
Finds specific files in specific backups. If <filename> is specified, all occurrences of <filename> in the backup are listed. <filename> can contain * and ? as wildcards. File names in [brackets] are interpreted as regular expression. Latest backup is searched by default. If entire path is specified, all available versions of the file are listed. If no <filename> is specified, a list of all available backups is shown.
@@ -116,7 +116,7 @@ Usage: find <storage-URL> ["<filename>"] [<options>]
# =============================================================================
> duplicati.commandline.exe help restore
Usage: restore <storage-URL> ["<filename>"] [<options>]
Usage: %CLI_EXE% restore <storage-URL> ["<filename>"] [<options>]
Restores <filename> to its original destination. If <filename> exists already, <filename> is changed to <filename-timestamp.extension>. To restore all files use "*" or leave empty.
@@ -134,7 +134,7 @@ Usage: restore <storage-URL> ["<filename>"] [<options>]
# =============================================================================
> duplicati.commandline.exe help delete
Usage: delete <storage-URL> [<options>]
Usage: %CLI_EXE% delete <storage-URL> [<options>]
Marks old data deleted and removes outdated dlist files. A backup is deleted when it is older than <keep-time> or when there are more newer versions than <keep-versions>. Data is considered old, when it is not required from any existing backup anymore.
@@ -154,7 +154,7 @@ Usage: delete <storage-URL> [<options>]
# =============================================================================
> duplicati.commandline.exe help compact
Usage: compact <storage-URL> [<options>]
Usage: %CLI_EXE% compact <storage-URL> [<options>]
Old data is not deleted immediately as in most cases only small parts of a dblock file are old data. When the amount of old data in a dblock file grows it might be worth to replace it. This is especially the case when the number of dblock files and thus the required storage space can be reduced. When backups are frequently made and only few files have changed, the uploaded dblock files are small. At some point it might make sense to replace a large number of small files with one large file. This is what compacting does.
@@ -171,7 +171,7 @@ Usage: compact <storage-URL> [<options>]
# =============================================================================
> duplicati.commandline.exe help compare
Usage: compare <storage-URL> [<base-version>] [<compare-to>] [<options>]
Usage: %CLI_EXE% compare <storage-URL> [<base-version>] [<compare-to>] [<options>]
Compares two backups and shows differences. If no versions are given, changes are shown between the two latest backups. The versions can either be timestamps or backup version numbers. If only one version is given, the most recent backup is compared to that version.
@@ -187,7 +187,7 @@ Usage: compare <storage-URL> [<base-version>] [<compare-to>] [<options>]
# =============================================================================
> duplicati.commandline.exe help create-report
Usage: create-report <storage-URL> <output-file> [<options>]
Usage: %CLI_EXE% create-report <storage-URL> <output-file> [<options>]
Analyses the backup and prepares a report with anonymous information. This report can be sent to the developers for a better analysis in case something went wrong.
@@ -197,7 +197,7 @@ Usage: create-report <storage-URL> <output-file> [<options>]
# =============================================================================
> duplicati.commandline.exe help repair
Usage: repair <storage-URL> [<options>]
Usage: %CLI_EXE% repair <storage-URL> [<options>]
Tries to repair the backup. If no local db is found or the db is empty, the db is re-created with data from the storage. If the db is in place but the remote storage is corrupt, the remote storage gets repaired with local data (if available).
@@ -206,7 +206,7 @@ Usage: repair <storage-URL> [<options>]
# =============================================================================
> duplicati.commandline.exe help purge
Usage: purge <storage-URL> <filenames> [<options>]
Usage: %CLI_EXE% purge <storage-URL> <filenames> [<options>]
Purges (removes) files from remote backup data. This command can either take a list of filenames or use the filters to choose which files to purge. The purge process creates new filesets on the remote destination with the purged files removed, and will start the compacting process after a purge. By default, the matching files are purged in all versions, but this can be limited by choosing one or more versions. To test what will happen, use the --dry-run flag.
@@ -228,11 +228,11 @@ Usage: purge <storage-URL> <filenames> [<options>]
> duplicati.commandline.exe help list-broken-files
> duplicati.commandline.exe help purge-broken-files
Usage: list-broken-files <storage-URL> [<options>]
Usage: %CLI_EXE% list-broken-files <storage-URL> [<options>]
Checks the database for missing data that cause files not not be restoreable. Files can become unrestoreable if remote data files are defect or missing. Use the list-broken-files command to see what the purge-broken-files command will remove.
Usage: purge-broken-files <storage-URL> [<options>]
Usage: %CLI_EXE% purge-broken-files <storage-URL> [<options>]
Removes all files from the database and remote storage that are no longer restoreable. Use this operation with caution, and only if you cannot recover the missing remote files, but want to continue a backup. Even with missing remote files, it may be possible to restore parts of the files that will be removed with this command.
@@ -244,7 +244,7 @@ Usage: purge-broken-files <storage-URL> [<options>]
> duplicati.commandline.exe help test
> duplicati.commandline.exe help verify
Usage: test <storage-URL> <samples> [<options>]
Usage: %CLI_EXE% test <storage-URL> <samples> [<options>]
Verifies integrity of a backup. A random sample of dlist, dindex, dblock files is downloaded, decrypted and the content is checked against recorded size values and data hashes. <samples> specifies the number of samples to be tested. If "all” is specified, all files in the backup will be tested. This is a rolling check, i.e. when executed another time different samples are verified than in the first run. A sample consists of 1 dlist, 1 dindex, 1 dblock.
@@ -262,21 +262,21 @@ Usage: test <storage-URL> <samples> [<options>]
> duplicati.commandline.exe help test-filters
> duplicati.commandline.exe help test-filter
Usage: test-filters <source-path> [<options>]
Usage: %CLI_EXE% test-filters <source-path> [<options>]
Scans the source files and tests against the filters specified, the console output shows which files and folders are examined and the result.
# =============================================================================
> duplicati.commandline.exe help affected
Usage: affected <storage-URL> <remote-filename> [<remote-filenames>] [<options>]
Usage: %CLI_EXE% affected <storage-URL> <remote-filename> [<remote-filenames>] [<options>]
Returns a report explaining what backup sets and files are affected by a remote file. You can use this option to see what source files are affected if one or more remote files are damaged or deleted. Notes that this command requires a local database to be present, if the database is not found automatically, you can set --dbpath to point to the database to use.
# =============================================================================
> duplicati.commandline.exe help vacuum
Usage: vacuum <storage-URL> [<options>]
Usage: %CLI_EXE% vacuum <storage-URL> [<options>]
Rebuilds the local database, repacking it into a minimal amount of disk space.
@@ -434,6 +434,15 @@ Whenever a size is required, you can use any of the following suffixes:
For speed limits, use the same format. If you enter 1MB this will be 1MB/sec.
# =============================================================================
> duplicati.commandline.exe help decimal
For entering decimal values you must use the English notation, with a period as decimal separator:
0.1
12.34
# =============================================================================
> duplicati.commandline.exe help filter
> duplicati.commandline.exe help filters
@@ -469,7 +478,7 @@ Duplicati has several built-in groups of filters, which include commonly exclude
Duplicati can send email notifications after each operation. Use the send-mail command to test this:
%MONO%"%APP_PATH%" send-mail --send-mail-to=<email-address>
"%APP_PATH%" send-mail --send-mail-to=<email-address>
--send-mail-to=<email-address>
View File
@@ -1,69 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B93E3BF0-DAA7-49B7-B07D-0559C5816735}</ProjectGuid>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.CommandLine.ConfigurationImporter</RootNamespace>
<AssemblyName>Duplicati.CommandLine.ConfigurationImporter</AssemblyName>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AssemblyName>Duplicati.CommandLine.ConfigurationImporter.Implementation</AssemblyName>
<Copyright>Copyright © 2024 Team Duplicati, MIT license</Copyright>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj" />
<ProjectReference Include="..\..\Server\Duplicati.Server.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{de3e5d4c-51ab-4e5e-bee8-e636cebfba65}</Project>
<Name>Duplicati.Library.Utility</Name>
</ProjectReference>
<ProjectReference Include="..\..\Server\Duplicati.Server.csproj">
<Project>{19e661d2-c5da-4f35-b3ee-7586e5734b5f}</Project>
<Name>Duplicati.Server</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
@@ -19,8 +19,9 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using Duplicati.Library.AutoUpdater;
using Duplicati.Library.RestAPI;
using Duplicati.Server.Serializable;
using Duplicati.Server.WebServer.RESTMethods;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -29,26 +30,32 @@ namespace Duplicati.CommandLine.ConfigurationImporter
{
public static class ConfigurationImporter
{
private static readonly string usageString = $"Usage: {nameof(ConfigurationImporter)}.exe <configuration-file> --import-metadata=(true | false) --server-datafolder=<folder containing Duplicati-server.sqlite>";
private static readonly string UsageString = $"Usage: {PackageHelper.GetExecutableName(PackageHelper.NamedExecutable.ConfigurationImporter)} <configuration-file> --import-metadata=(true | false) --server-datafolder=<folder containing Duplicati-server.sqlite>";
public static void Main(string[] args)
public static int Main(string[] args)
{
if (args.Length != 3)
{
throw new ArgumentException($"Incorrect number of input arguments. {ConfigurationImporter.usageString}");
Console.WriteLine($"Incorrect number of input arguments.");
Console.WriteLine(UsageString);
return 1;
}
string configurationFile = args[0];
Dictionary<string, string> importOptions = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args.Skip(1).ToList());
if (!importOptions.TryGetValue("import-metadata", out string importMetadataString))
{
throw new ArgumentException($"Invalid import-metadata argument. {ConfigurationImporter.usageString}");
Console.WriteLine($"Missing import-metadata argument.");
Console.WriteLine(UsageString);
return 1;
}
bool importMetadata = Duplicati.Library.Utility.Utility.ParseBool(importMetadataString, false);
if (!importOptions.TryGetValue("server-datafolder", out string serverDatafolder))
{
throw new ArgumentException($"Invalid server-datafolder argument. {ConfigurationImporter.usageString}");
Console.WriteLine($"Missing server-datafolder argument.");
Console.WriteLine(UsageString);
return 1;
}
Dictionary<string, string> advancedOptions = new Dictionary<string, string>
@@ -56,8 +63,10 @@ namespace Duplicati.CommandLine.ConfigurationImporter
{ "server-datafolder", serverDatafolder }
};
ImportExportStructure importedStructure = Backups.ImportBackup(configurationFile, importMetadata, () => ConfigurationImporter.ReadPassword($"Password for {configurationFile}: "), advancedOptions);
ImportExportStructure importedStructure = BackupImportExportHandler.ImportBackup(configurationFile, importMetadata, () => ConfigurationImporter.ReadPassword($"Password for {configurationFile}: "), advancedOptions);
Console.WriteLine($"Imported \"{importedStructure.Backup.Name}\" with ID {importedStructure.Backup.ID} and local database at {importedStructure.Backup.DBPath}.");
return 0;
}
private static string ReadPassword(string prompt)
@@ -1,35 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Duplicati.CommandLine.ConfigurationImporter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Duplicati.CommandLine.ConfigurationImporter")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("B93E3BF0-DAA7-49B7-B07D-0559C5816735")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("2.0.0.7")]
[assembly: AssemblyVersion("2.0.0.7")]
[assembly: AssemblyFileVersion("2.0.0.7")]
@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />
</startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.3" newVersion="4.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.4.0" newVersion="3.0.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -1,263 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{81765A64-3661-4E3E-B850-2F6F87A51F74}</ProjectGuid>
<OutputType>Exe</OutputType>
<Prefer32Bit>False</Prefer32Bit>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.CommandLine</RootNamespace>
<AssemblyName>Duplicati.CommandLine</AssemblyName>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<ApplicationIcon>TrayWarning.ico</ApplicationIcon>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseMSBuildEngine>false</UseMSBuildEngine>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<EnvironmentVariables>
<EnvironmentVariables>
<Variable name="AUTOUPDATER_Duplicati_SKIP_UPDATE" value="1" />
</EnvironmentVariables>
</EnvironmentVariables>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=3.0.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.KeyVault.Core.3.0.4\lib\net461\Microsoft.Azure.KeyVault.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Edm, Version=5.8.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Edm.5.8.4\lib\net40\Microsoft.Data.Edm.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.OData, Version=5.8.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.OData.5.8.4\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Services.Client, Version=5.8.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Services.Client.5.8.4\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Rest.ClientRuntime.2.3.24\lib\net461\Microsoft.Rest.ClientRuntime.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime.Azure, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.19\lib\net461\Microsoft.Rest.ClientRuntime.Azure.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Spatial, Version=5.8.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Spatial.5.8.4\lib\net40\System.Spatial.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Help.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Commands.cs" />
<Compile Include="ConsoleOutput.cs" />
<Compile Include="Strings.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj">
<Project>{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}</Project>
<Name>Duplicati.Library.Backend.AzureBlob</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\File\Duplicati.Library.Backend.File.csproj">
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
<Name>Duplicati.Library.Backend.File</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
<Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
<Name>Duplicati.Library.Backend.Idrivee2</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
<Name>Duplicati.Library.Backend.Jottacloud</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Rclone\Duplicati.Library.Backend.Rclone.csproj">
<Project>{851a1cb8-3ceb-41b4-956f-34d760d2a8e5}</Project>
<Name>Duplicati.Library.Backend.Rclone</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
<Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
<Name>Duplicati.Library.Backend.Sia</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Tardigrade\Duplicati.Library.Backend.Tardigrade.csproj">
<Project>{9a04cb37-da72-4008-9703-3ac5191974e9}</Project>
<Name>Duplicati.Library.Backend.Tardigrade</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Compression\Duplicati.Library.Compression.csproj">
<Project>{19ECCE09-B5EB-406C-8C57-BAC66997D469}</Project>
<Name>Duplicati.Library.Compression</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
</ProjectReference>
<ProjectReference Include="..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj">
<Project>{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}</Project>
<Name>Duplicati.Library.DynamicLoader</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Interface\Duplicati.Library.Interface.csproj">
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
<Name>Duplicati.Library.Interface</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Logging\Duplicati.Library.Logging.csproj">
<Project>{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}</Project>
<Name>Duplicati.Library.Logging</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Main\Duplicati.Library.Main.csproj">
<Project>{10D2D1B7-C664-41D8-9B3A-00040C3D421B}</Project>
<Name>Duplicati.Library.Main</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj">
<Project>{52826615-7964-47FE-B4B3-1B2DBDF605B9}</Project>
<Name>Duplicati.Library.Modules.Builtin</Name>
</ProjectReference>
<ProjectReference Include="..\License\Duplicati.License.csproj">
<Project>{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}</Project>
<Name>Duplicati.License</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj">
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj">
<Project>{1BFAE226-8364-4086-825C-BB83F6F3EE4C}</Project>
<Name>Duplicati.Library.Backend.CloudFiles</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj">
<Project>{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}</Project>
<Name>Duplicati.Library.Backend.S3</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
<Project>{FF2BF37C-E502-4C98-BEA0-701671DDFA08}</Project>
<Name>Duplicati.Library.Backend.SSHv2</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj">
<Project>{C0270709-2A40-43B5-8CF1-69581B9FA2A1}</Project>
<Name>Duplicati.Library.Backend.TahoeLAFS</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj">
<Project>{BAE27510-8B5D-44B2-B33E-372A98908041}</Project>
<Name>Duplicati.Library.Backend.WEBDAV</Name>
</ProjectReference>
<ProjectReference Include="BackendTool\Duplicati.CommandLine.BackendTool.csproj">
<Project>{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}</Project>
<Name>Duplicati.CommandLine.BackendTool</Name>
</ProjectReference>
<ProjectReference Include="BackendTester\Duplicati.CommandLine.BackendTester.csproj">
<Project>{E7280DCA-7776-4A73-B9B5-41FD77FC8799}</Project>
<Name>Duplicati.CommandLine.BackendTester</Name>
</ProjectReference>
<ProjectReference Include="..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj">
<Project>{7E119745-1F62-43F0-936C-F312A1912C0B}</Project>
<Name>Duplicati.Library.AutoUpdater</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj">
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
<Name>Duplicati.Library.Backend.OneDrive</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Localization\Duplicati.Library.Localization.csproj">
<Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
<Name>Duplicati.Library.Localization</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\GoogleServices\Duplicati.Library.Backend.GoogleServices.csproj">
<Project>{5489181D-950C-44AF-873C-45EB0A3B6BD2}</Project>
<Name>Duplicati.Library.Backend.GoogleServices</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\OpenStack\Duplicati.Library.Backend.OpenStack.csproj">
<Project>{D9E4E686-423C-48EC-A392-404E7C00860C}</Project>
<Name>Duplicati.Library.Backend.OpenStack</Name>
</ProjectReference>
<ProjectReference Include="RecoveryTool\Duplicati.CommandLine.RecoveryTool.csproj">
<Project>{4A010589-76E6-4F05-A5C4-4598D5DF11F8}</Project>
<Name>Duplicati.CommandLine.RecoveryTool</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Backblaze\Duplicati.Library.Backend.Backblaze.csproj">
<Project>{61C43D61-4368-4942-84A3-1EB623F4EF2A}</Project>
<Name>Duplicati.Library.Backend.Backblaze</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Mega\Duplicati.Library.Backend.Mega.csproj">
<Project>{6643A5AE-AB38-453F-ADCE-408E35A81A83}</Project>
<Name>Duplicati.Library.Backend.Mega</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Box\Duplicati.Library.Backend.Box.csproj">
<Project>{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}</Project>
<Name>Duplicati.Library.Backend.Box</Name>
</ProjectReference>
<ProjectReference Include="..\Library\UsageReporter\Duplicati.Library.UsageReporter.csproj">
<Project>{BB014EA5-CE2C-4444-8D30-38983A0E8553}</Project>
<Name>Duplicati.Library.UsageReporter</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
<ProjectReference Include="..\Tools\Duplicati.Tools.csproj">
<Project>{0797AA22-C5DD-4950-BB60-34765AB8C6DD}</Project>
<Name>Duplicati.Tools</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Common\Duplicati.Library.Common.csproj">
<Project>{D63E53E4-A458-4C2F-914D-92F715F58ACF}</Project>
<Name>Duplicati.Library.Common</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Storj\Duplicati.Library.Backend.Storj.csproj">
<Project>{AE035E01-C917-4F13-A35E-78F21C1A2F17}</Project>
<Name>Duplicati.Library.Backend.Storj</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.manifest">
<SubType>Designer</SubType>
</None>
<None Include="Duplicati.snk" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<EmbeddedResource Include="help.txt" />
<Content Include="TrayWarning.ico" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
Binary file not shown.
@@ -1,33 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Duplicati.CommandLine")]
[assembly: AssemblyDescription("A commandline version of Duplicati")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Duplicati Team")]
[assembly: AssemblyProduct("Duplicati.CommandLine")]
[assembly: AssemblyCopyright("MIT license, Copyright © Duplicati Team 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("bfc1d214-8825-417d-8e2c-be4bb0d6524d")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("2.0.0.7")]
[assembly: AssemblyFileVersion("2.0.0.7")]
@@ -1,201 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4A010589-76E6-4F05-A5C4-4598D5DF11F8}</ProjectGuid>
<OutputType>Exe</OutputType>
<Prefer32Bit>False</Prefer32Bit>
<RootNamespace>Duplicati.CommandLine.RecoveryTool</RootNamespace>
<AssemblyName>Duplicati.CommandLine.RecoveryTool</AssemblyName>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<UseMSBuildEngine>false</UseMSBuildEngine>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<EnvironmentVariables>
<EnvironmentVariables>
<Variable name="AUTOUPDATER_Duplicati_SKIP_UPDATE" value="1" />
</EnvironmentVariables>
</EnvironmentVariables>
<Commandlineparameters>index /Users/kenneth/testdata/recovery --targetpath=/Users/kenneth/testdata/recovery-restored</Commandlineparameters>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=3.0.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.Azure.KeyVault.Core.3.0.4\lib\net461\Microsoft.Azure.KeyVault.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.Rest.ClientRuntime.2.3.24\lib\net461\Microsoft.Rest.ClientRuntime.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime.Azure, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.19\lib\net461\Microsoft.Rest.ClientRuntime.Azure.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>
<ItemGroup>
<Compile Include="FileIndex.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Download.cs" />
<Compile Include="Help.cs" />
<Compile Include="Index.cs" />
<Compile Include="List.cs" />
<Compile Include="Recompress.cs" />
<Compile Include="Restore.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj">
<Project>{7E119745-1F62-43F0-936C-F312A1912C0B}</Project>
<Name>Duplicati.Library.AutoUpdater</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj">
<Project>{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}</Project>
<Name>Duplicati.Library.Backend.AzureBlob</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj">
<Project>{1BFAE226-8364-4086-825C-BB83F6F3EE4C}</Project>
<Name>Duplicati.Library.Backend.CloudFiles</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\File\Duplicati.Library.Backend.File.csproj">
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
<Name>Duplicati.Library.Backend.File</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj">
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\GoogleServices\Duplicati.Library.Backend.GoogleServices.csproj">
<Project>{5489181D-950C-44AF-873C-45EB0A3B6BD2}</Project>
<Name>Duplicati.Library.Backend.GoogleServices</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
<Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
<Name>Duplicati.Library.Backend.Idrivee2</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
<Name>Duplicati.Library.Backend.Jottacloud</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj">
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
<Name>Duplicati.Library.Backend.OneDrive</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OpenStack\Duplicati.Library.Backend.OpenStack.csproj">
<Project>{D9E4E686-423C-48EC-A392-404E7C00860C}</Project>
<Name>Duplicati.Library.Backend.OpenStack</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Rclone\Duplicati.Library.Backend.Rclone.csproj">
<Project>{851a1cb8-3ceb-41b4-956f-34d760d2a8e5}</Project>
<Name>Duplicati.Library.Backend.Rclone</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj">
<Project>{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}</Project>
<Name>Duplicati.Library.Backend.S3</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
<Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
<Name>Duplicati.Library.Backend.Sia</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
<Project>{FF2BF37C-E502-4C98-BEA0-701671DDFA08}</Project>
<Name>Duplicati.Library.Backend.SSHv2</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj">
<Project>{C0270709-2A40-43B5-8CF1-69581B9FA2A1}</Project>
<Name>Duplicati.Library.Backend.TahoeLAFS</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Tardigrade\Duplicati.Library.Backend.Tardigrade.csproj">
<Project>{9a04cb37-da72-4008-9703-3ac5191974e9}</Project>
<Name>Duplicati.Library.Backend.Tardigrade</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj">
<Project>{BAE27510-8B5D-44B2-B33E-372A98908041}</Project>
<Name>Duplicati.Library.Backend.WEBDAV</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Compression\Duplicati.Library.Compression.csproj">
<Project>{19ECCE09-B5EB-406C-8C57-BAC66997D469}</Project>
<Name>Duplicati.Library.Compression</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj">
<Project>{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}</Project>
<Name>Duplicati.Library.DynamicLoader</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Interface\Duplicati.Library.Interface.csproj">
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
<Name>Duplicati.Library.Interface</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Main\Duplicati.Library.Main.csproj">
<Project>{10D2D1B7-C664-41D8-9B3A-00040C3D421B}</Project>
<Name>Duplicati.Library.Main</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Backblaze\Duplicati.Library.Backend.Backblaze.csproj">
<Project>{61C43D61-4368-4942-84A3-1EB623F4EF2A}</Project>
<Name>Duplicati.Library.Backend.Backblaze</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Mega\Duplicati.Library.Backend.Mega.csproj">
<Project>{6643A5AE-AB38-453F-ADCE-408E35A81A83}</Project>
<Name>Duplicati.Library.Backend.Mega</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Box\Duplicati.Library.Backend.Box.csproj">
<Project>{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}</Project>
<Name>Duplicati.Library.Backend.Box</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj">
<Project>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</Project>
<Name>Duplicati.Library.Backend.AlternativeFTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Common\Duplicati.Library.Common.csproj">
<Project>{D63E53E4-A458-4C2F-914D-92F715F58ACF}</Project>
<Name>Duplicati.Library.Common</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Storj\Duplicati.Library.Backend.Storj.csproj">
<Project>{AE035E01-C917-4F13-A35E-78F21C1A2F17}</Project>
<Name>Duplicati.Library.Backend.Storj</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="help.txt" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Description>RecoveryTool for Duplicati</Description>
<AssemblyName>Duplicati.CommandLine.RecoveryTool.Implementation</AssemblyName>
<Copyright>Copyright © 2024 Team Duplicati, MIT license</Copyright>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj" />
<ProjectReference Include="..\..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj" />
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj" />
<ProjectReference Include="..\..\Library\Main\Duplicati.Library.Main.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="help.txt" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
Binary file not shown.

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