From fddf549a9c82915bc031145dae6867f7087bf6b8 Mon Sep 17 00:00:00 2001 From: "B. Stack" Date: Sun, 7 Jan 2024 22:24:42 -0500 Subject: add upstream 13.3 --- Changelog.txt | 13 +- FreeFileSync/Build/Resources/Icons.zip | Bin 360142 -> 354626 bytes FreeFileSync/Build/Resources/Languages.zip | Bin 558162 -> 558241 bytes FreeFileSync/Build/Resources/cacert.pem | 195 ++++++++++++++++------- FreeFileSync/Source/RealTimeSync/application.cpp | 11 +- FreeFileSync/Source/afs/abstract.h | 18 +-- FreeFileSync/Source/afs/ftp.cpp | 23 +-- FreeFileSync/Source/afs/gdrive.cpp | 8 +- FreeFileSync/Source/afs/native.cpp | 8 +- FreeFileSync/Source/afs/sftp.cpp | 8 +- FreeFileSync/Source/application.cpp | 15 +- FreeFileSync/Source/base/db_file.cpp | 3 +- FreeFileSync/Source/base/synchronization.cpp | 14 +- FreeFileSync/Source/base/versioning.cpp | 10 +- FreeFileSync/Source/base/versioning.h | 2 +- FreeFileSync/Source/ui/main_dlg.cpp | 129 +++++++-------- FreeFileSync/Source/ui/search_grid.cpp | 2 +- FreeFileSync/Source/version/version.h | 2 +- 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 Binary files a/FreeFileSync/Build/Resources/Icons.zip and b/FreeFileSync/Build/Resources/Icons.zip differ diff --git a/FreeFileSync/Build/Resources/Languages.zip b/FreeFileSync/Build/Resources/Languages.zip index c63556fe..7e2f93fe 100644 Binary files a/FreeFileSync/Build/Resources/Languages.zip and b/FreeFileSync/Build/Resources/Languages.zip 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(e.what())); - terminateProcess(static_cast(FfsExitCode::exception)); - } - //catch (...) -> Windows: let it crash and create mini dump!!! Linux/macOS: std::exception::what() logged to console return static_cast(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& onDeleteTargetFile /*throw X*/, //accummulated delta != file size! consider ADS, sparse, compressed files const zen::IoCallback& notifyUnbufferedIO /*throw X*/); - - struct FolderCopyResult - { - std::optional 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 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(e.what())); - terminateProcess(static_cast(FfsExitCode::exception)); - } - //catch (...) -> Windows: let it crash and create mini dump!!! Linux/macOS: std::exception::what() logged to console return static_cast(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(), file.getFilePrint()}, .cmpVar = activeCmpVar_, .fileSize = file.getFileSize(), - } - ); + }); 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(), 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(), targetPath, copyFilePermissions_, singleThread_); //throw FileError } catch (FileError&) { @@ -2405,10 +2402,7 @@ bool createBaseFolder(BaseFolderPair& baseFolder, bool copyFilePermissions, Phas if (const std::optional parentPath = AFS::getParentPath(folderPath)) AFS::createFolderIfMissingRecursion(*parentPath); //throw FileError - AFS::FolderCopyResult result = AFS::copyNewFolder(baseFolder.getAbstractPath(), 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(), 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 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 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& 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 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& 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 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 = '.'; } -- cgit