summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2024-01-07 22:24:42 -0500
committerB. Stack <bgstack15@gmail.com>2024-01-07 22:24:42 -0500
commitfddf549a9c82915bc031145dae6867f7087bf6b8 (patch)
treecfde8e0ec31d4a6490fee2b4eb47bb71991818d3
parentadd upstream 13.2 (diff)
downloadFreeFileSync-13.3.tar.gz
FreeFileSync-13.3.tar.bz2
FreeFileSync-13.3.zip
add upstream 13.313.3
-rw-r--r--Changelog.txt13
-rw-r--r--FreeFileSync/Build/Resources/Icons.zipbin360142 -> 354626 bytes
-rw-r--r--FreeFileSync/Build/Resources/Languages.zipbin558162 -> 558241 bytes
-rw-r--r--FreeFileSync/Build/Resources/cacert.pem195
-rw-r--r--FreeFileSync/Source/RealTimeSync/application.cpp11
-rw-r--r--FreeFileSync/Source/afs/abstract.h18
-rw-r--r--FreeFileSync/Source/afs/ftp.cpp23
-rw-r--r--FreeFileSync/Source/afs/gdrive.cpp8
-rw-r--r--FreeFileSync/Source/afs/native.cpp8
-rw-r--r--FreeFileSync/Source/afs/sftp.cpp8
-rw-r--r--FreeFileSync/Source/application.cpp15
-rw-r--r--FreeFileSync/Source/base/db_file.cpp3
-rw-r--r--FreeFileSync/Source/base/synchronization.cpp14
-rw-r--r--FreeFileSync/Source/base/versioning.cpp10
-rw-r--r--FreeFileSync/Source/base/versioning.h2
-rw-r--r--FreeFileSync/Source/ui/main_dlg.cpp129
-rw-r--r--FreeFileSync/Source/ui/search_grid.cpp2
-rw-r--r--FreeFileSync/Source/version/version.h2
18 files changed, 251 insertions, 210 deletions
diff --git a/Changelog.txt b/Changelog.txt
index 063a76eb..834c4a6a 100644
--- a/Changelog.txt
+++ b/Changelog.txt
@@ -1,7 +1,16 @@
-FreeFileSync 13.2
+FreeFileSync 13.3 [2024-01-07]
+------------------------------
+Completed CASA security assessment for Google Drive
+Use system temp folder for auto-updating
+Ignore errors when setting directory attributes is unsupported
+Save GUI sync log file even when cancelled
+Fixed Business Edition install over existing installation
+
+
+FreeFileSync 13.2 [2023-11-23]
------------------------------
Complete high-DPI/Retina display support (macOS)
-Prevent versioning files from being moved to versioning recursively
+Prevent files from being moved to versioning recursively
Fixed tooltip line wrap bug for moved files (Windows)
Return first FTP parsing error when trying multiple variants
Allow file times from the future for Linux-style FTP listing
diff --git a/FreeFileSync/Build/Resources/Icons.zip b/FreeFileSync/Build/Resources/Icons.zip
index dc23279f..22025c9f 100644
--- a/FreeFileSync/Build/Resources/Icons.zip
+++ b/FreeFileSync/Build/Resources/Icons.zip
Binary files differ
diff --git a/FreeFileSync/Build/Resources/Languages.zip b/FreeFileSync/Build/Resources/Languages.zip
index c63556fe..7e2f93fe 100644
--- a/FreeFileSync/Build/Resources/Languages.zip
+++ b/FreeFileSync/Build/Resources/Languages.zip
Binary files differ
diff --git a/FreeFileSync/Build/Resources/cacert.pem b/FreeFileSync/Build/Resources/cacert.pem
index 9551dfd8..d8fda7d1 100644
--- a/FreeFileSync/Build/Resources/cacert.pem
+++ b/FreeFileSync/Build/Resources/cacert.pem
@@ -1,7 +1,7 @@
##
## Bundle of CA Root Certificates
##
-## Certificate data from Mozilla as of: Tue Aug 22 03:12:04 2023 GMT
+## Certificate data from Mozilla as of: Tue Dec 12 04:12:04 2023 GMT
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
@@ -14,7 +14,7 @@
## Just configure this file as the SSLCACertificateFile.
##
## Conversion done with mk-ca-bundle.pl version 1.29.
-## SHA256: 0ff137babc6a5561a9cfbe9f29558972e5b528202681b7d3803d03a3e82922bd
+## SHA256: 1970dd65858925d68498d2356aea6d03f764422523c5887deca8ce3ba9e1f845
##
@@ -200,27 +200,6 @@ vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
-----END CERTIFICATE-----
-Security Communication Root CA
-==============================
------BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
-U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
-HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
-U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
-8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
-DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
-5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
-DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
-JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
-DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
-0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
-mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
-s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
-6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
-FL39vmwLAw==
------END CERTIFICATE-----
-
XRamp Global CA Root
====================
-----BEGIN CERTIFICATE-----
@@ -669,39 +648,6 @@ YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
kpeDMdmztcpHWD9f
-----END CERTIFICATE-----
-Autoridad de Certificacion Firmaprofesional CIF A62634068
-=========================================================
------BEGIN CERTIFICATE-----
-MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA
-BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
-MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw
-QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB
-NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD
-Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P
-B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY
-7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH
-ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI
-plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX
-MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX
-LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK
-bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU
-vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud
-EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH
-DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
-cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA
-bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx
-ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx
-51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk
-R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP
-T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f
-Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl
-osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR
-crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR
-saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD
-KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi
-6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
------END CERTIFICATE-----
-
Izenpe.com
==========
-----BEGIN CERTIFICATE-----
@@ -3449,3 +3395,140 @@ TFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuYo7Ey7Nmj
PqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDwN/zIIX8/syQbPYtuzE2wFg2W
HYMfRsCbvUOZ58SWLs5fyQ==
-----END CERTIFICATE-----
+
+TrustAsia Global Root CA G3
+===========================
+-----BEGIN CERTIFICATE-----
+MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEMBQAwWjELMAkG
+A1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMM
+G1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAeFw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEw
+MTlaMFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMu
+MSQwIgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNST1QY4Sxz
+lZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqKAtCWHwDNBSHvBm3dIZwZ
+Q0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/V
+P68czH5GX6zfZBCK70bwkPAPLfSIC7Epqq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1Ag
+dB4SQXMeJNnKziyhWTXAyB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm
+9WAPzJMshH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gXzhqc
+D0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAvkV34PmVACxmZySYg
+WmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msTf9FkPz2ccEblooV7WIQn3MSAPmea
+mseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jAuPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCF
+TIcQcf+eQxuulXUtgQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj
+7zjKsK5Xf/IhMBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E
+BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4wM8zAQLpw6o1
+D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2XFNFV1pF1AWZLy4jVe5jaN/T
+G3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNj
+duMNhXJEIlU/HHzp/LgV6FL6qj6jITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstl
+cHboCoWASzY9M/eVVHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys
++TIxxHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1onAX1daBli
+2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d7XB4tmBZrOFdRWOPyN9y
+aFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2NtjjgKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsAS
+ZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFR
+JQJ6+N1rZdVtTTDIZbpoFGWsJwt0ivKH
+-----END CERTIFICATE-----
+
+TrustAsia Global Root CA G4
+===========================
+-----BEGIN CERTIFICATE-----
+MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMwWjELMAkGA1UE
+BhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMMG1Ry
+dXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0yMTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJa
+MFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQw
+IgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AATxs8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbwLxYI+hW8
+m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJijYzBhMA8GA1UdEwEB/wQF
+MAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mDpm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/
+pDHel4NZg6ZvccveMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AA
+bbd+NvBNEU/zy4k6LHiRUKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xk
+dUfFVZDj/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA==
+-----END CERTIFICATE-----
+
+CommScope Public Trust ECC Root-01
+==================================
+-----BEGIN CERTIFICATE-----
+MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMwTjELMAkGA1UE
+BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz
+dCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNaFw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYT
+AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg
+RUNDIFJvb3QtMDEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLx
+eP0CflfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJEhRGnSjot
+6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggqhkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2
+Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liW
+pDVfG2XqYZpwI7UNo5uSUm9poIyNStDuiw7LR47QjRE=
+-----END CERTIFICATE-----
+
+CommScope Public Trust ECC Root-02
+==================================
+-----BEGIN CERTIFICATE-----
+MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMwTjELMAkGA1UE
+BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz
+dCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRaFw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYT
+AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg
+RUNDIFJvb3QtMDIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/M
+MDALj2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmUv4RDsNuE
+SgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggqhkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9
+Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/nich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs7
+3u1Z/GtMMH9ZzkXpc2AVmkzw5l4lIhVtwodZ0LKOag==
+-----END CERTIFICATE-----
+
+CommScope Public Trust RSA Root-01
+==================================
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQELBQAwTjELMAkG
+A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU
+cnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNV
+BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1
+c3QgUlNBIFJvb3QtMDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45Ft
+nYSkYZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslhsuitQDy6
+uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0alDrJLpA6lfO741GIDuZNq
+ihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3OjWiE260f6GBfZumbCk6SP/F2krfxQapWs
+vCQz0b2If4b19bJzKo98rwjyGpg/qYFlP8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/c
+Zip8UlF1y5mO6D1cv547KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTif
+BSeolz7pUcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/kQO9
+lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JOHg9O5j9ZpSPcPYeo
+KFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkBEa801M/XrmLTBQe0MXXgDW1XT2mH
++VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6UCBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm4
+5P3luG0wDQYJKoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6
+NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQnmhUQo8mUuJM
+3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+QgvfKNmwrZggvkN80V4aCRck
+jXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2vtrV0KnahP/t1MJ+UXjulYPPLXAziDslg+Mkf
+Foom3ecnf+slpoq9uC02EJqxWE2aaE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/W
+NyVntHKLr4W96ioDj8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+
+o/E4Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0wlREQKC6/
+oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHnYfkUyq+Dj7+vsQpZXdxc
+1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVocicCMb3SgazNNtQEo/a2tiRc7ppqEvOuM
+6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw
+-----END CERTIFICATE-----
+
+CommScope Public Trust RSA Root-02
+==================================
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQELBQAwTjELMAkG
+A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU
+cnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNV
+BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1
+c3QgUlNBIFJvb3QtMDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3V
+rCLENQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0kyI9p+Kx
+7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1CrWDaSWqVcN3SAOLMV2MC
+e5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxzhkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2W
+Wy09X6GDRl224yW4fKcZgBzqZUPckXk2LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rp
+M9kzXzehxfCrPfp4sOcsn/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIf
+hs1w/tkuFT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5kQMr
+eyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3wNemKfrb3vOTlycE
+VS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6vwQcQeKwRoi9C8DfF8rhW3Q5iLc4t
+Vn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7Gx
+cJXvYXowDQYJKoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB
+KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3+VGXu6TwYofF
+1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbymeAPnCKfWxkxlSaRosTKCL4BWa
+MS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3NyqpgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xd
+gSGn2rtO/+YHqP65DSdsu3BaVXoT6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2O
+HG1QAk8mGEPej1WFsQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+Nm
+YWvtPjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2dlklyALKr
+dVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670v64fG9PiO/yzcnMcmyiQ
+iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN
+lM47ni3niAIi9G7oyOzWPPO5std3eqx7
+-----END CERTIFICATE-----
diff --git a/FreeFileSync/Source/RealTimeSync/application.cpp b/FreeFileSync/Source/RealTimeSync/application.cpp
index df148001..39daab05 100644
--- a/FreeFileSync/Source/RealTimeSync/application.cpp
+++ b/FreeFileSync/Source/RealTimeSync/application.cpp
@@ -209,18 +209,11 @@ wxLayoutDirection Application::GetLayoutDirection() const { return fff::getLayou
int Application::OnRun()
{
- try
- {
#if wxUSE_EXCEPTIONS
#error why is wxWidgets uncaught exception handling enabled!?
#endif
+
+ //exception => Windows: let it crash and create mini dump!!! Linux/macOS: std::exception::what() logged to console
[[maybe_unused]] const int rc = wxApp::OnRun();
- }
- catch (const std::bad_alloc& e) //the only kind of exception we don't want crash dumps for
- {
- notifyAppError(utfTo<std::wstring>(e.what()));
- terminateProcess(static_cast<int>(FfsExitCode::exception));
- }
- //catch (...) -> Windows: let it crash and create mini dump!!! Linux/macOS: std::exception::what() logged to console
return static_cast<int>(FfsExitCode::success); //process exit code
}
diff --git a/FreeFileSync/Source/afs/abstract.h b/FreeFileSync/Source/afs/abstract.h
index 6fc74c37..951fdf86 100644
--- a/FreeFileSync/Source/afs/abstract.h
+++ b/FreeFileSync/Source/afs/abstract.h
@@ -289,14 +289,9 @@ struct AbstractFileSystem //THREAD-SAFETY: "const" member functions must model t
const std::function<void()>& onDeleteTargetFile /*throw X*/,
//accummulated delta != file size! consider ADS, sparse, compressed files
const zen::IoCallback& notifyUnbufferedIO /*throw X*/);
-
- struct FolderCopyResult
- {
- std::optional<zen::FileError> errorAttribs;
- };
//already existing: fail
//symlink handling: follow
- static FolderCopyResult copyNewFolder(const AbstractPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions); //throw FileError
+ static void copyNewFolder(const AbstractPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions); //throw FileError
//already existing: fail
static void copySymlink(const AbstractPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions); //throw FileError
@@ -425,7 +420,7 @@ private:
//symlink handling: follow
//already existing: fail
- virtual FolderCopyResult copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const = 0; //throw FileError
+ virtual void copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const = 0; //throw FileError
//already existing: fail
virtual void copySymlinkForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const = 0; //throw FileError
@@ -557,7 +552,7 @@ void AbstractFileSystem::moveAndRenameItem(const AbstractPath& pathFrom, const A
inline
-AbstractFileSystem::FolderCopyResult AbstractFileSystem::copyNewFolder(const AbstractPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) //throw FileError
+void AbstractFileSystem::copyNewFolder(const AbstractPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) //throw FileError
{
using namespace zen;
@@ -566,15 +561,12 @@ AbstractFileSystem::FolderCopyResult AbstractFileSystem::copyNewFolder(const Abs
//already existing: fail
createFolderPlain(targetPath); //throw FileError
- FolderCopyResult result;
if (copyFilePermissions)
- result.errorAttribs = FileError(replaceCpy(_("Cannot write permissions of %x."), L"%x", fmtPath(getDisplayPath(targetPath))),
+ throw FileError(replaceCpy(_("Cannot write permissions of %x."), L"%x", fmtPath(getDisplayPath(targetPath))),
_("Operation not supported between different devices."));
-
- return result;
}
else
- return sourcePath.afsDevice.ref().copyNewFolderForSameAfsType(sourcePath.afsPath, targetPath, copyFilePermissions); //throw FileError
+ sourcePath.afsDevice.ref().copyNewFolderForSameAfsType(sourcePath.afsPath, targetPath, copyFilePermissions); //throw FileError
}
diff --git a/FreeFileSync/Source/afs/ftp.cpp b/FreeFileSync/Source/afs/ftp.cpp
index 55bf79bf..96abc473 100644
--- a/FreeFileSync/Source/afs/ftp.cpp
+++ b/FreeFileSync/Source/afs/ftp.cpp
@@ -402,12 +402,9 @@ public:
setCurlOption({CURLOPT_TCP_KEEPALIVE, 1}); //throw SysError
//=> CURLOPT_TCP_KEEPIDLE (=delay) and CURLOPT_TCP_KEEPINTVL both default to 60 sec
-warn_static("remove after test") //https://freefilesync.org/forum/viewtopic.php?p=41482#p41482
-#if 0
- setCurlOption({CURLOPT_TCP_KEEPIDLE, 30 /*[sec]*/}); //throw SysError
- setCurlOption({CURLOPT_TCP_KEEPINTVL, 30 /*[sec]*/}); //throw SysError
-#endif
-
+ //default is 60 sec (sufficient!?):
+ //setCurlOption({CURLOPT_TCP_KEEPIDLE, 30 /*[sec]*/}); //throw SysError
+ //setCurlOption({CURLOPT_TCP_KEEPINTVL, 30 /*[sec]*/}); //throw SysError
std::optional<SysError> socketException;
@@ -558,7 +555,7 @@ warn_static("remove after test") //https://freefilesync.org/forum/viewtopic.php?
long ftpStatusCode = 0; //optional
/*const CURLcode rc =*/ ::curl_easy_getinfo(easyHandle_, CURLINFO_RESPONSE_CODE, &ftpStatusCode);
//https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes
- assert(ftpStatusCode == 0 || 400 <= ftpStatusCode && ftpStatusCode < 600);
+ assert(rcPerf == CURLE_OPERATION_TIMEDOUT || rcPerf == CURLE_ABORTED_BY_CALLBACK || ftpStatusCode == 0 || 400 <= ftpStatusCode && ftpStatusCode < 600);
if (ftpStatusCode != 0)
throw SysErrorFtpProtocol(formatSystemError("curl_easy_perform", formatCurlStatusCode(rcPerf), errorMsg), ftpStatusCode);
@@ -1900,8 +1897,8 @@ void ftpFileDownload(const FtpLogin& login, const AfsPath& afsFilePath, //throw
{CURLOPT_WRITEFUNCTION, onBytesReceivedWrapper},
{CURLOPT_IGNORE_CONTENT_LENGTH, 1L}, //skip FTP "SIZE" command before download (=> download until actual EOF if file size changes)
- //{CURLOPT_BUFFERSIZE, 256 * 1024} -> defaults is 16 kB which seems to correspond to SSL packet size
- //=> setting larget buffers size does nothing (recv still returns only 16 kB)
+ //{CURLOPT_BUFFERSIZE, 256 * 1024} -> default is 16 kB which seems to correspond to TLS packet size
+ //=> setting larger buffer size does nothing (recv still returns only 16 kB)
}, true /*requestUtf8*/); //throw SysError, SysErrorPassword, SysErrorFtpProtocol
});
}
@@ -2440,19 +2437,13 @@ private:
//symlink handling: follow
//already existing: fail
- FolderCopyResult copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const override //throw FileError
+ void copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const override //throw FileError
{
//already existing: fail
AFS::createFolderPlain(targetPath); //throw FileError
- FolderCopyResult result;
- try
- {
if (copyFilePermissions)
throw FileError(replaceCpy(_("Cannot write permissions of %x."), L"%x", fmtPath(AFS::getDisplayPath(targetPath))), _("Operation not supported by device."));
- }
- catch (const FileError& e) { result.errorAttribs = e; }
- return result;
}
//already existing: fail
diff --git a/FreeFileSync/Source/afs/gdrive.cpp b/FreeFileSync/Source/afs/gdrive.cpp
index 3fac2c0d..33f04c88 100644
--- a/FreeFileSync/Source/afs/gdrive.cpp
+++ b/FreeFileSync/Source/afs/gdrive.cpp
@@ -3704,19 +3704,13 @@ private:
//symlink handling: follow
//already existing: fail
- FolderCopyResult copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const override //throw FileError
+ void copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const override //throw FileError
{
//already existing: 1. fails or 2. creates duplicate (unlikely)
AFS::createFolderPlain(targetPath); //throw FileError
- FolderCopyResult result;
- try
- {
if (copyFilePermissions)
throw FileError(replaceCpy(_("Cannot write permissions of %x."), L"%x", fmtPath(AFS::getDisplayPath(targetPath))), _("Operation not supported by device."));
- }
- catch (const FileError& e) { result.errorAttribs = e; }
- return result;
}
//already existing: fail
diff --git a/FreeFileSync/Source/afs/native.cpp b/FreeFileSync/Source/afs/native.cpp
index 8b58ec10..53c5b671 100644
--- a/FreeFileSync/Source/afs/native.cpp
+++ b/FreeFileSync/Source/afs/native.cpp
@@ -583,7 +583,7 @@ private:
//symlink handling: follow
//already existing: fail
- FolderCopyResult copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const override //throw FileError
+ void copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const override //throw FileError
{
initComForThread(); //throw FileError
@@ -592,16 +592,14 @@ private:
zen::createDirectory(targetPathNative); //throw FileError, ErrorTargetExisting
- FolderCopyResult result;
try
{
copyDirectoryAttributes(sourcePathNative, targetPathNative); //throw FileError
+ }
+ catch (FileError&) {} //[!] too unimportant + too frequent for external devices, e.g. "ERROR_INVALID_PARAMETER [SetFileInformationByHandle(FileBasicInfo)]" on Samba share
if (copyFilePermissions)
copyItemPermissions(sourcePathNative, targetPathNative, ProcSymlink::follow); //throw FileError
- }
- catch (const FileError& e) { result.errorAttribs = e; }
- return result;
}
//already existing: fail
diff --git a/FreeFileSync/Source/afs/sftp.cpp b/FreeFileSync/Source/afs/sftp.cpp
index 795b5a01..392f595b 100644
--- a/FreeFileSync/Source/afs/sftp.cpp
+++ b/FreeFileSync/Source/afs/sftp.cpp
@@ -1793,19 +1793,13 @@ private:
//symlink handling: follow
//already existing: fail
- FolderCopyResult copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const override //throw FileError
+ void copyNewFolderForSameAfsType(const AfsPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions) const override //throw FileError
{
//already existing: fail
AFS::createFolderPlain(targetPath); //throw FileError
- FolderCopyResult result;
- try
- {
if (copyFilePermissions)
throw FileError(replaceCpy(_("Cannot write permissions of %x."), L"%x", fmtPath(AFS::getDisplayPath(targetPath))), _("Operation not supported by device."));
- }
- catch (const FileError& e) { result.errorAttribs = e; }
- return result;
}
//already existing: fail
diff --git a/FreeFileSync/Source/application.cpp b/FreeFileSync/Source/application.cpp
index 38f677d8..d479fb22 100644
--- a/FreeFileSync/Source/application.cpp
+++ b/FreeFileSync/Source/application.cpp
@@ -243,19 +243,12 @@ wxLayoutDirection Application::GetLayoutDirection() const { return getLayoutDire
int Application::OnRun()
{
- try
- {
#if wxUSE_EXCEPTIONS
#error why is wxWidgets uncaught exception handling enabled!?
#endif
+
+ //exception => Windows: let it crash and create mini dump!!! Linux/macOS: std::exception::what() logged to console
[[maybe_unused]] const int rc = wxApp::OnRun();
- }
- catch (const std::bad_alloc& e) //the only kind of exception we don't want crash dumps for
- {
- notifyAppError(utfTo<std::wstring>(e.what()));
- terminateProcess(static_cast<int>(FfsExitCode::exception));
- }
- //catch (...) -> Windows: let it crash and create mini dump!!! Linux/macOS: std::exception::what() logged to console
return static_cast<int>(exitCode_);
}
@@ -624,9 +617,9 @@ void Application::runBatchMode(const Zstring& globalConfigFilePath, const XmlBat
if (statusHandler.taskCancelled() && *statusHandler.taskCancelled() == CancelReason::user)
; /* user cancelled => don't run post sync command
+ => don't run post sync action
=> don't send email notification
- => don't play sound notification
- => don't run post sync action */
+ => don't play sound notification */
else
{
//--------------------- post sync command ----------------------
diff --git a/FreeFileSync/Source/base/db_file.cpp b/FreeFileSync/Source/base/db_file.cpp
index e5dac708..e24afe89 100644
--- a/FreeFileSync/Source/base/db_file.cpp
+++ b/FreeFileSync/Source/base/db_file.cpp
@@ -606,8 +606,7 @@ private:
.right = InSyncDescrFile{file.getLastWriteTime<SelectSide::right>(), file.getFilePrint<SelectSide::right>()},
.cmpVar = activeCmpVar_,
.fileSize = file.getFileSize<SelectSide::left>(),
- }
- );
+ });
toPreserve.insert(fileName);
}
else //not in sync: preserve last synchronous state
diff --git a/FreeFileSync/Source/base/synchronization.cpp b/FreeFileSync/Source/base/synchronization.cpp
index f72430f3..8bcc37c2 100644
--- a/FreeFileSync/Source/base/synchronization.cpp
+++ b/FreeFileSync/Source/base/synchronization.cpp
@@ -723,8 +723,8 @@ void copySymlink(const AbstractPath& sourcePath, const AbstractPath& targetPath,
{ parallelScope([sourcePath, targetPath, copyFilePermissions] { AFS::copySymlink(sourcePath, targetPath, copyFilePermissions); /*throw FileError*/ }, singleThread); }
inline
-AFS::FolderCopyResult copyNewFolder(const AbstractPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions, std::mutex& singleThread) //throw FileError
-{ return parallelScope([sourcePath, targetPath, copyFilePermissions] { return AFS::copyNewFolder(sourcePath, targetPath, copyFilePermissions); /*throw FileError*/ }, singleThread); }
+void copyNewFolder(const AbstractPath& sourcePath, const AbstractPath& targetPath, bool copyFilePermissions, std::mutex& singleThread) //throw FileError
+{ parallelScope([sourcePath, targetPath, copyFilePermissions] { return AFS::copyNewFolder(sourcePath, targetPath, copyFilePermissions); /*throw FileError*/ }, singleThread); }
inline
void removeFilePlain(const AbstractPath& filePath, std::mutex& singleThread) //throw FileError
@@ -2175,10 +2175,7 @@ void FolderPairSyncer::synchronizeFolderInt(FolderPair& folder, SyncOperation sy
try
{
//already existing: fail
- AFS::FolderCopyResult result = parallel::copyNewFolder(folder.getAbstractPath<sideSrc>(), targetPath, copyFilePermissions_, singleThread_); //throw FileError
-
- if (result.errorAttribs) //log only; no popup
- acb_.logMessage(result.errorAttribs->toString(), PhaseCallback::MsgType::warning); //throw ThreadStopRequest
+ parallel::copyNewFolder(folder.getAbstractPath<sideSrc>(), targetPath, copyFilePermissions_, singleThread_); //throw FileError
}
catch (FileError&)
{
@@ -2405,10 +2402,7 @@ bool createBaseFolder(BaseFolderPair& baseFolder, bool copyFilePermissions, Phas
if (const std::optional<AbstractPath> parentPath = AFS::getParentPath(folderPath))
AFS::createFolderIfMissingRecursion(*parentPath); //throw FileError
- AFS::FolderCopyResult result = AFS::copyNewFolder(baseFolder.getAbstractPath<sideSrc>(), folderPath, copyFilePermissions); //throw FileError
-
- if (result.errorAttribs) //log only; no popup
- callback.logMessage(result.errorAttribs->toString(), PhaseCallback::MsgType::warning); //throw X
+ AFS::copyNewFolder(baseFolder.getAbstractPath<sideSrc>(), folderPath, copyFilePermissions); //throw FileError
}
else
AFS::createFolderIfMissingRecursion(folderPath); //throw FileError
diff --git a/FreeFileSync/Source/base/versioning.cpp b/FreeFileSync/Source/base/versioning.cpp
index 5c33541d..8189fbd3 100644
--- a/FreeFileSync/Source/base/versioning.cpp
+++ b/FreeFileSync/Source/base/versioning.cpp
@@ -181,7 +181,7 @@ void moveExistingItemToVersioning(const AbstractPath& sourcePath, const Abstract
}
-void FileVersioner::checkPathConflict(const AbstractPath& itemPath) const //throw FileError
+void FileVersioner::checkPathConflict(const AbstractPath& itemPath, const Zstring& relativePath) const //throw FileError
{
if (std::optional<PathDependency> pd = getPathDependency(itemPath, versioningFolderPath_))
{
@@ -190,7 +190,7 @@ void FileVersioner::checkPathConflict(const AbstractPath& itemPath) const //thro
//prevent files from being moved to versioning recursively:
throw FileError(trimCpy(replaceCpy(replaceCpy(_("Cannot move %x to %y."),
L"%x", L'\n' + fmtPath(AFS::getDisplayPath(itemPath))),
- L"%y", L'\n' + fmtPath(AFS::getDisplayPath(versioningFolderPath_)))),
+ L"%y", L'\n' + fmtPath(AFS::getDisplayPath(generateVersionedPath(relativePath))))),
_("Item already located in the versioning folder."));
}
}
@@ -198,7 +198,7 @@ void FileVersioner::checkPathConflict(const AbstractPath& itemPath) const //thro
void FileVersioner::revisionFile(const FileDescriptor& fileDescr, const Zstring& relativePath, const IoCallback& notifyUnbufferedIO /*throw X*/) const //throw FileError, X
{
- checkPathConflict(fileDescr.path); //throw FileError
+ checkPathConflict(fileDescr.path, relativePath); //throw FileError
if (const std::optional<AFS::ItemType> type = AFS::getItemTypeIfExists(fileDescr.path)) //throw FileError
{
@@ -241,7 +241,7 @@ void FileVersioner::revisionFileImpl(const FileDescriptor& fileDescr, const Zstr
void FileVersioner::revisionSymlink(const AbstractPath& linkPath, const Zstring& relativePath) const //throw FileError
{
- checkPathConflict(linkPath); //throw FileError
+ checkPathConflict(linkPath, relativePath); //throw FileError
if (AFS::itemExists(linkPath)) //throw FileError
revisionSymlinkImpl(linkPath, relativePath, nullptr /*onBeforeMove*/); //throw FileError
@@ -267,7 +267,7 @@ void FileVersioner::revisionFolder(const AbstractPath& folderPath, const Zstring
const std::function<void(const std::wstring& displayPathFrom, const std::wstring& displayPathTo)>& onBeforeFolderMove /*throw X*/,
const IoCallback& notifyUnbufferedIO /*throw X*/) const
{
- checkPathConflict(folderPath); //throw FileError
+ checkPathConflict(folderPath, relativePath); //throw FileError
//no error situation if directory is not existing! manual deletion relies on it!
if (const std::optional<AFS::ItemType> type = AFS::getItemTypeIfExists(folderPath)) //throw FileError
diff --git a/FreeFileSync/Source/base/versioning.h b/FreeFileSync/Source/base/versioning.h
index 3512e24a..2f852cd1 100644
--- a/FreeFileSync/Source/base/versioning.h
+++ b/FreeFileSync/Source/base/versioning.h
@@ -66,7 +66,7 @@ private:
FileVersioner (const FileVersioner&) = delete;
FileVersioner& operator=(const FileVersioner&) = delete;
- void checkPathConflict(const AbstractPath& itemPath) const; //throw FileError
+ void checkPathConflict(const AbstractPath& itemPath, const Zstring& relativePath) const; //throw FileError
void revisionFileImpl(const FileDescriptor& fileDescr, const Zstring& relativePath, //throw FileError, X
const std::function<void(const std::wstring& displayPathFrom, const std::wstring& displayPathTo)>& onBeforeMove,
diff --git a/FreeFileSync/Source/ui/main_dlg.cpp b/FreeFileSync/Source/ui/main_dlg.cpp
index 446baa4c..fc7078ea 100644
--- a/FreeFileSync/Source/ui/main_dlg.cpp
+++ b/FreeFileSync/Source/ui/main_dlg.cpp
@@ -4867,32 +4867,43 @@ void MainDialog::onStartSync(wxCommandEvent& event)
fullSyncLog_->totalTime += r.summary.totalTime;
+ //"consume" fullSyncLog_, but don't reset: there may be items remaining for manual operations or re-sync!
+ ProcessSummary fullSummary = r.summary;
+ fullSummary.startTime = std::exchange(fullSyncLog_->startTime, std::chrono::system_clock::now());
+ fullSummary.totalTime = std::exchange(fullSyncLog_->totalTime, {});
+ //let's *not* redetermine "ProcessSummary::result", even if errors occured during manual operations!
+
+ ErrorLog fullLog = std::exchange(fullSyncLog_->log, {});
+
+ auto logMsg2 =[&](const std::wstring& msg, MessageType type)
+ {
+ logMsg(fullLog, msg, type);
+ logMsg(r.errorLog.ref(), msg, type);
+ };
+
+ AbstractPath logFolderPath = createAbstractPath(guiCfg.mainCfg.altLogFolderPathPhrase); //optional
+ if (AFS::isNullPath(logFolderPath))
+ logFolderPath = createAbstractPath(globalCfg_.logFolderPhrase);
+ assert(!AFS::isNullPath(logFolderPath)); //mandatory! but still: let's include fall back
+ if (AFS::isNullPath(logFolderPath))
+ logFolderPath = createAbstractPath(getLogFolderDefaultPath());
+
+ AbstractPath logFilePath = AFS::appendRelPath(logFolderPath, generateLogFileName(globalCfg_.logFormat, fullSummary));
+ //e.g. %AppData%\FreeFileSync\Logs\Backup FreeFileSync 2013-09-15 015052.123 [Error].log
+
+ auto notifyStatusNoThrow = [&](std::wstring&& msg) { try { statusHandler.updateStatus(std::move(msg)); /*throw CancelProcess*/ } catch (CancelProcess&) {} };
+
+
if (statusHandler.taskCancelled())
/* user cancelled => don't run post sync command
+ => don't run post sync action
=> don't send email notification
- => don't save log file (=> treat sync attempt like a manual operation)
- => don't update last sync stats for the selected cfg files
=> don't play sound notification
- => don't run post sync action */
+ (=> DO save log file: sync attempt is more than just a "manual operation")
+ (=> DO update last sync stats for the selected cfg files) */
assert(statusHandler.taskCancelled() == CancelReason::user); //"stop on first error" is only for ffs_batch
else
{
- //"consume" fullSyncLog_, but don't reset: there may be items remaining for manual operations or re-sync!
- ProcessSummary fullSummary = r.summary;
- fullSummary.startTime = std::exchange(fullSyncLog_->startTime, std::chrono::system_clock::now());
- fullSummary.totalTime = std::exchange(fullSyncLog_->totalTime, {});
- //let's *not* redetermine "ProcessSummary::result", even if errors occured during manual operations!
-
- ErrorLog fullLog = std::exchange(fullSyncLog_->log, {});
-
- auto logMsg2 =[&](const std::wstring& msg, MessageType type)
- {
- logMsg(fullLog, msg, type);
- logMsg(r.errorLog.ref(), msg, type);
- };
-
- auto notifyStatusNoThrow = [&](std::wstring&& msg) { try { statusHandler.updateStatus(std::move(msg)); /*throw CancelProcess*/ } catch (CancelProcess&) {} };
-
//--------------------- post sync command ----------------------
if (const Zstring cmdLine = trimCpy(expandMacros(guiCfg.mainCfg.postSyncCommand));
!cmdLine.empty())
@@ -4920,16 +4931,6 @@ void MainDialog::onStartSync(wxCommandEvent& event)
}
//--------------------- email notification ----------------------
- AbstractPath logFolderPath = createAbstractPath(guiCfg.mainCfg.altLogFolderPathPhrase); //optional
- if (AFS::isNullPath(logFolderPath))
- logFolderPath = createAbstractPath(globalCfg_.logFolderPhrase);
- assert(!AFS::isNullPath(logFolderPath)); //mandatory! but still: let's include fall back
- if (AFS::isNullPath(logFolderPath))
- logFolderPath = createAbstractPath(getLogFolderDefaultPath());
-
- AbstractPath logFilePath = AFS::appendRelPath(logFolderPath, generateLogFileName(globalCfg_.logFormat, fullSummary));
- //e.g. %AppData%\FreeFileSync\Logs\Backup FreeFileSync 2013-09-15 015052.123 [Error].log
-
if (const std::string notifyEmail = trimCpy(guiCfg.mainCfg.emailNotifyAddress);
!notifyEmail.empty())
if (guiCfg.mainCfg.emailNotifyCondition == ResultsNotification::always ||
@@ -4944,45 +4945,45 @@ void MainDialog::onStartSync(wxCommandEvent& event)
sendLogAsEmail(notifyEmail, fullSummary, fullLog, logFilePath, notifyStatusNoThrow); //throw FileError
}
catch (const FileError& e) { logMsg2(e.toString(), MSG_TYPE_ERROR); }
+ }
- //--------------------- save log file ----------------------
- try //create not before destruction: 1. avoid issues with FFS trying to sync open log file 2. include status in log file name without extra rename
- {
- //do NOT use tryReportingError()! saving log files should not be cancellable!
- saveLogFile(logFilePath, fullSummary, fullLog, globalCfg_.logfilesMaxAgeDays, globalCfg_.logFormat, logFilePathsToKeep, notifyStatusNoThrow); //throw FileError
- }
- catch (const FileError& e)
- {
- logMsg2(e.toString(), MSG_TYPE_ERROR);
+ //--------------------- save log file ----------------------
+ try //create not before destruction: 1. avoid issues with FFS trying to sync open log file 2. include status in log file name without extra rename
+ {
+ //do NOT use tryReportingError()! saving log files should not be cancellable!
+ saveLogFile(logFilePath, fullSummary, fullLog, globalCfg_.logfilesMaxAgeDays, globalCfg_.logFormat, logFilePathsToKeep, notifyStatusNoThrow); //throw FileError
+ }
+ catch (const FileError& e)
+ {
+ logMsg2(e.toString(), MSG_TYPE_ERROR);
- const AbstractPath logFileDefaultPath = AFS::appendRelPath(createAbstractPath(getLogFolderDefaultPath()), generateLogFileName(globalCfg_.logFormat, fullSummary));
- if (logFilePath != logFileDefaultPath) //fallback: log file *must* be saved no matter what!
- try
- {
- logFilePath = logFileDefaultPath;
- saveLogFile(logFileDefaultPath, fullSummary, fullLog, globalCfg_.logfilesMaxAgeDays, globalCfg_.logFormat, logFilePathsToKeep, notifyStatusNoThrow); //throw FileError
- }
- catch (const FileError& e2) { logMsg2(e2.toString(), MSG_TYPE_ERROR); assert(false); } //should never happen!!!
- }
+ const AbstractPath logFileDefaultPath = AFS::appendRelPath(createAbstractPath(getLogFolderDefaultPath()), generateLogFileName(globalCfg_.logFormat, fullSummary));
+ if (logFilePath != logFileDefaultPath) //fallback: log file *must* be saved no matter what!
+ try
+ {
+ logFilePath = logFileDefaultPath;
+ saveLogFile(logFileDefaultPath, fullSummary, fullLog, globalCfg_.logfilesMaxAgeDays, globalCfg_.logFormat, logFilePathsToKeep, notifyStatusNoThrow); //throw FileError
+ }
+ catch (const FileError& e2) { logMsg2(e2.toString(), MSG_TYPE_ERROR); assert(false); } //should never happen!!!
+ }
- //--------- update last sync stats for the selected cfg files ---------
- const ErrorLogStats& fullLogStats = getStats(fullLog);
+ //--------- update last sync stats for the selected cfg files ---------
+ const ErrorLogStats& fullLogStats = getStats(fullLog);
- cfggrid::getDataView(*m_gridCfgHistory).setLastRunStats(activeConfigFiles_,
- {
- logFilePath,
- std::chrono::system_clock::to_time_t(fullSummary.startTime),
- fullSummary.result,
- fullSummary.statsProcessed.items,
- fullSummary.statsProcessed.bytes,
- fullSummary.totalTime,
- fullLogStats.error,
- fullLogStats.warning,
- });
- //re-apply selection: sort order changed if sorted by last sync time
- cfggrid::addAndSelect(*m_gridCfgHistory, activeConfigFiles_, false /*scrollToSelection*/);
- //m_gridCfgHistory->Refresh(); <- implicit in last call
- }
+ cfggrid::getDataView(*m_gridCfgHistory).setLastRunStats(activeConfigFiles_,
+ {
+ logFilePath,
+ std::chrono::system_clock::to_time_t(fullSummary.startTime),
+ fullSummary.result,
+ fullSummary.statsProcessed.items,
+ fullSummary.statsProcessed.bytes,
+ fullSummary.totalTime,
+ fullLogStats.error,
+ fullLogStats.warning,
+ });
+ //re-apply selection: sort order changed if sorted by last sync time
+ cfggrid::addAndSelect(*m_gridCfgHistory, activeConfigFiles_, false /*scrollToSelection*/);
+ //m_gridCfgHistory->Refresh(); <- implicit in last call
//---------------------------------------------------------------------------
setLastOperationLog(r.summary, r.errorLog.ptr());
diff --git a/FreeFileSync/Source/ui/search_grid.cpp b/FreeFileSync/Source/ui/search_grid.cpp
index 37214c05..1d0f0e0c 100644
--- a/FreeFileSync/Source/ui/search_grid.cpp
+++ b/FreeFileSync/Source/ui/search_grid.cpp
@@ -74,7 +74,7 @@ template <bool respectCase>
ptrdiff_t findRow(const Grid& grid, //return -1 if no matching row found
const std::wstring& searchString,
bool searchAscending,
- size_t rowFirst, //specify area to search:
+ size_t rowFirst, //range to search:
size_t rowLast) // [rowFirst, rowLast)
{
if (auto prov = grid.getDataProvider())
diff --git a/FreeFileSync/Source/version/version.h b/FreeFileSync/Source/version/version.h
index b0c5c523..5f566458 100644
--- a/FreeFileSync/Source/version/version.h
+++ b/FreeFileSync/Source/version/version.h
@@ -3,7 +3,7 @@
namespace fff
{
-const char ffsVersion[] = "13.2"; //internal linkage!
+const char ffsVersion[] = "13.3"; //internal linkage!
const char FFS_VERSION_SEPARATOR = '.';
}
bgstack15