diff --git a/AUTHORS b/AUTHORS index 23df9fe22ff..19829d09c17 100644 --- a/AUTHORS +++ b/AUTHORS @@ -116,6 +116,7 @@ Dmitry Saveliev (dsaveliev) domain <32405309+szu17dmy@users.noreply.github.com> Domenic Horner Dominik Heidler (asdil12) +Elias <1elias.bauer@gmail.com> Elias Jarlebring (jarlebring) Elliot Huffman Emil Hessman (ceh) @@ -287,6 +288,7 @@ Sergey Mishin (ralder) Sertonix <83883937+Sertonix@users.noreply.github.com> Severin von Wnuck-Lipinski Shaarad Dalvi <60266155+shaaraddalvi@users.noreply.github.com> +Shablone <20610621+Shablone@users.noreply.github.com> Shivam Kumar <155747305+maishivamhoo123@users.noreply.github.com> Simon Mwepu Simon Pickup diff --git a/assets/windows/syncthing.exe.manifest b/assets/windows/syncthing.exe.manifest new file mode 100644 index 00000000000..3757f2abc88 --- /dev/null +++ b/assets/windows/syncthing.exe.manifest @@ -0,0 +1,8 @@ + + + + + detached + + + \ No newline at end of file diff --git a/build.go b/build.go index 35c568d9854..fdb6fc481bb 100644 --- a/build.go +++ b/build.go @@ -718,7 +718,7 @@ func shouldBuildSyso(dir string) (string, error) { } jsonPath := filepath.Join(dir, "versioninfo.json") - err = os.WriteFile(jsonPath, bs, 0o644) + err = os.WriteFile(jsonPath, bs, 0o666) if err != nil { return "", errors.New("failed to create " + jsonPath + ": " + err.Error()) } @@ -732,9 +732,18 @@ func shouldBuildSyso(dir string) (string, error) { sysoPath := filepath.Join(dir, "cmd", "syncthing", "resource.syso") // See https://github.com/josephspurrier/goversioninfo#command-line-flags - arm := strings.HasPrefix(goarch, "arm") - a64 := strings.Contains(goarch, "64") - if _, err := runError("goversioninfo", "-o", sysoPath, fmt.Sprintf("-arm=%v", arm), fmt.Sprintf("-64=%v", a64)); err != nil { + // For manifest see https://learn.microsoft.com/en-us/windows/console/console-allocation-policy + isARM := strings.HasPrefix(goarch, "arm") + is64Bit := strings.Contains(goarch, "64") + + args := []string{ + "-manifest=assets/windows/syncthing.exe.manifest", // console-allocation-policy + "-o", sysoPath, // output path + fmt.Sprintf("-arm=%v", isARM), + fmt.Sprintf("-64=%v", is64Bit), + } + + if _, err := runError("goversioninfo", args...); err != nil { return "", errors.New("failed to create " + sysoPath + ": " + err.Error()) } @@ -774,7 +783,7 @@ func copyFile(src, dst string, perm os.FileMode) error { } copy: - os.MkdirAll(filepath.Dir(dst), 0o777) + os.MkdirAll(filepath.Dir(dst), os.ModePerm) if err := os.WriteFile(dst, in, perm); err != nil { return err } @@ -1423,7 +1432,7 @@ func writeCompatJSON() { continue } bs, _ := json.MarshalIndent(e, "", " ") - if err := os.WriteFile("compat.json", bs, 0o644); err != nil { + if err := os.WriteFile("compat.json", bs, 0o666); err != nil { log.Fatal("Writing compat.json:", err) } return diff --git a/cmd/infra/stcrashreceiver/diskstore.go b/cmd/infra/stcrashreceiver/diskstore.go index 2e3788be70a..e13c8bad8bb 100644 --- a/cmd/infra/stcrashreceiver/diskstore.go +++ b/cmd/infra/stcrashreceiver/diskstore.go @@ -42,7 +42,7 @@ type currentFile struct { } func (d *diskStore) Serve(ctx context.Context) { - if err := os.MkdirAll(d.dir, 0o700); err != nil { + if err := os.MkdirAll(d.dir, os.ModePerm); err != nil { log.Println("Creating directory:", err) return } @@ -62,7 +62,7 @@ func (d *diskStore) Serve(ctx context.Context) { case entry := <-d.inbox: path := d.fullPath(entry.path) - if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil { + if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil { log.Println("Creating directory:", err) continue } @@ -77,7 +77,7 @@ func (d *diskStore) Serve(ctx context.Context) { log.Println("Failed to compress crash report:", err) continue } - if err := os.WriteFile(path, buf.Bytes(), 0o600); err != nil { + if err := os.WriteFile(path, buf.Bytes(), 0o666); err != nil { log.Printf("Failed to write %s: %v", entry.path, err) _ = os.Remove(path) continue diff --git a/cmd/infra/stcrashreceiver/util.go b/cmd/infra/stcrashreceiver/util.go index ad58b5caa54..f0d5b4ccc18 100644 --- a/cmd/infra/stcrashreceiver/util.go +++ b/cmd/infra/stcrashreceiver/util.go @@ -52,5 +52,5 @@ func compressAndWrite(bs []byte, fullPath string) error { gw.Close() // Create an output file with the compressed report - return os.WriteFile(fullPath, buf.Bytes(), 0o644) + return os.WriteFile(fullPath, buf.Bytes(), 0o666) } diff --git a/cmd/infra/strelaypoolsrv/main.go b/cmd/infra/strelaypoolsrv/main.go index 0871d59821d..fee62dbda3c 100644 --- a/cmd/infra/strelaypoolsrv/main.go +++ b/cmd/infra/strelaypoolsrv/main.go @@ -612,7 +612,7 @@ func saveRelays(file string, relays []*relay) error { for _, relay := range relays { content += relay.uri.String() + "\n" } - return os.WriteFile(file, []byte(content), 0o777) + return os.WriteFile(file, []byte(content), 0o666) } func createTestCertificate() tls.Certificate { diff --git a/cmd/syncthing/decrypt/decrypt.go b/cmd/syncthing/decrypt/decrypt.go index 4545e119c80..862566a8533 100644 --- a/cmd/syncthing/decrypt/decrypt.go +++ b/cmd/syncthing/decrypt/decrypt.go @@ -167,7 +167,7 @@ func (c *CLI) process(srcFs fs.Filesystem, dstFs fs.Filesystem, path string) err var plainFd fs.File if dstFs != nil { - if err := dstFs.MkdirAll(filepath.Dir(plainFi.Name), 0o700); err != nil { + if err := dstFs.MkdirAll(filepath.Dir(plainFi.Name), fs.ModePerm); err != nil { return fmt.Errorf("%s: %w", plainFi.Name, err) } diff --git a/cmd/syncthing/hideconsole_windows.go b/cmd/syncthing/hideconsole_windows.go index f51e8acc3e8..ef084891468 100644 --- a/cmd/syncthing/hideconsole_windows.go +++ b/cmd/syncthing/hideconsole_windows.go @@ -7,5 +7,5 @@ package main type buildSpecificOptions struct { - HideConsole bool `name:"no-console" help:"Hide console window" env:"STHIDECONSOLE"` + HideConsole bool `name:"no-console" help:"Hide console window (Always enabled on Windows 11 24H2 and later)" env:"STHIDECONSOLE"` } diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index bd35c666793..35ed25c34d5 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -673,7 +673,7 @@ func auditWriter(auditFile string) io.Writer { } else { auditFlags = os.O_WRONLY | os.O_CREATE | os.O_APPEND } - fd, err = os.OpenFile(auditFile, auditFlags, 0o600) + fd, err = os.OpenFile(auditFile, auditFlags, 0o666) if err != nil { slog.Error("Failed to open audit file", slogutil.Error(err)) os.Exit(svcutil.ExitError.AsInt()) diff --git a/cmd/syncthing/monitor.go b/cmd/syncthing/monitor.go index 35f98600b87..7b0cf2186cd 100644 --- a/cmd/syncthing/monitor.go +++ b/cmd/syncthing/monitor.go @@ -479,7 +479,7 @@ func (f *autoclosedFile) ensureOpenLocked() error { // We open the file for write only, and create it if it doesn't exist. flags := os.O_WRONLY | os.O_CREATE | os.O_APPEND - fd, err := os.OpenFile(f.name, flags, 0o644) + fd, err := os.OpenFile(f.name, flags, 0o666) if err != nil { return err } diff --git a/cmd/syncthing/openurl_windows.go b/cmd/syncthing/openurl_windows.go index 2f5eca8efe9..a89ea4b77b4 100644 --- a/cmd/syncthing/openurl_windows.go +++ b/cmd/syncthing/openurl_windows.go @@ -9,8 +9,27 @@ package main -import "os/exec" +import "golang.org/x/sys/windows" func openURL(url string) error { - return exec.Command("cmd.exe", "/C", "start "+url).Run() + urlPtr, err := windows.UTF16PtrFromString(url) + if err != nil { + return err + } + + verbPtr, err := windows.UTF16PtrFromString("open") + if err != nil { + return err + } + + err = windows.ShellExecute( + 0, // hwnd + verbPtr, // operation + urlPtr, // file + nil, // parameters + nil, // directory + windows.SW_SHOWNORMAL, + ) + + return err } diff --git a/gui/default/assets/lang/lang-hr.json b/gui/default/assets/lang/lang-hr.json index 83d6a2bcf8d..35a1cf6c3ca 100644 --- a/gui/default/assets/lang/lang-hr.json +++ b/gui/default/assets/lang/lang-hr.json @@ -11,6 +11,7 @@ "Add Device": "Dodaj uređaj", "Add Folder": "Dodaj mapu", "Add Remote Device": "Dodaj udaljeni uređaj", + "Add devices from the introducer to our device list, for mutually shared folders.": "Dodaj uređaje od posrednika u našu listu uređaja, za međusobno dijeljene mape.", "Add filter entry": "Dodaj unos filtra", "Add ignore patterns": "Dodaj uzorke zanemarivanja", "Add new folder?": "Dodati novu mapu?", @@ -187,6 +188,7 @@ "GUI Authentication Password": "Lozinka za GUI autentifikacju", "GUI Authentication User": "Korisnik za GUI autentifikacju", "GUI Authentication: Set User and Password": "GUI autentifikacija: Postavite korisnika i lozinku", + "GUI Listen Address": "GUI adresa za slušanje", "GUI Override Directory": "Direktorij za nadjačavanje GUI-ja", "GUI Theme": "Tema GUI-ja", "General": "Općenito", @@ -214,6 +216,8 @@ "Incorrect user name or password.": "Neispravno korisničko ime ili lozinka.", "Info": "Informacije", "Internally used paths:": "Interno korištene staze:", + "Introduced By": "Uveden od", + "Introducer": "Posrednik", "Introduction": "Uvod", "Inversion of the given condition (i.e. do not exclude)": "Inverzija zadanog uvjeta (tj. ne isključuj)", "Keep Versions": "Zadrži verzije", @@ -248,6 +252,7 @@ "Log tailing paused. Scroll to the bottom to continue.": "Praćenje zapisa je pauzirano. Pomaknite se na dno kako biste nastavili.", "Login failed, see Syncthing logs for details.": "Prijava nije uspjela. Pogledaj detalje u odjeljku zapisima sinkronizacije.", "Logs": "Zapisi", + "Maintain an index of all blocks in the folder, enabling reuse of blocks from other files when syncing changes. Disable to reduce database size at the cost of not being able to reuse blocks across files.": "Održavaj indeks svih blokova u mapi, što omogućava ponovnu upotrebu blokova iz drugih datoteka pri sinkronizaciji promjena. Onemogući da smanjiš veličinu baze podataka, uz cijenu nemogućnosti ponovne upotrebe blokova između datoteka.", "Major Upgrade": "Velika nadogradnja", "Mass actions": "Masovne radnje", "Maximum Age": "Maksimalna starost", @@ -401,6 +406,7 @@ "Support Bundle": "Paket podrške", "Sync Extended Attributes": "Sinkroniziraj proširena svojstva", "Sync Ownership": "Sinkroniziraj vlasništvo", + "Sync Protocol Listen Addresses": "Adrese za slušanje sinkronizacijskog protokola", "Sync Status": "Stanje sinkronizacije", "Syncing": "Sinkroniziranje", "Syncthing device ID for \"{%devicename%}\"": "Syncthing ID uređaja za „{{devicename}}“", diff --git a/gui/default/syncthing/core/aboutModalView.html b/gui/default/syncthing/core/aboutModalView.html index 6fac805f156..09cab925abf 100644 --- a/gui/default/syncthing/core/aboutModalView.html +++ b/gui/default/syncthing/core/aboutModalView.html @@ -30,7 +30,7 @@

The Syncthing Authors

-Jakob Borg, Audrius Butkevicius, Simon Frei, Tomasz Wilczyński, Alexander Graf, Alexandre Viau, Anderson Mesquita, André Colomb, Antony Male, Ben Schulz, bt90, Caleb Callaway, Daniel Harte, Emil Lundberg, Eric P, Evgeny Kuznetsov, greatroar, Lars K.W. Gohlke, Lode Hoste, Marcus B Spencer, Michael Ploujnikov, Ross Smith II, Stefan Tatschner, Tommy van der Vorst, Wulf Weich, Adam Piggott, Adel Qalieh, Aleksey Vasenev, Alessandro G., Alex Ionescu, Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Andreas Sommer, andresvia, Andrew Rabert, Andrey D, andyleap, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, ardevd, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Ashish Bhate, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Beat Reichenbach, Ben Norcombe, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benno Fünfstück, Benny Ng, boomsquared, Boqin Qin, Boris Rybalkin, Brendan Long, Catfriend1, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Christian Kujau, Christian Prescott, chucic, cjc7373, Colin Kennedy, Cromefire_, cui, Cyprien Devillez, d-volution, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Daniel Padrta, Daniil Gentili, Darshil Chanpura, dashangcun, David Rimmer, DeflateAwning, Denis A., Dennis Wilson, derekriemer, DerRockWolf, desbma, Devon G. Redekopp, digital, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, domain, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Eng Zer Jun, entity0xfe, Epifeny, epifeny, Eric Lesiuta, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, georgespatton, ghjklw, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, guangwu, gudvinr, Gusted, Han Boetes, HansK-p, Harrison Jones, Hazem Krimi, Heiko Zuerker, Hireworks, Hugo Locurcio, Iain Barnett, Ian Johnson, ignacy123, Iskander Sharipov, Jaakko Hannikainen, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jaspitta, Jaya Chithra, Jaya Kumar, Jeffery To, jelle van der Waa, Jens Diemer, Jochen Voss, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jose Manuel Delicado, JRNitre, jtagcat, Julian Lehrhuber, Jörg Thalheim, Jędrzej Kula, Kapil Sareen, Karol Różycki, Kebin Liu, Keith Harrison, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., klemens, Kurt Fitzner, kylosus, Lars Lehtonen, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, LSmithx2, Luiz Angelo Daros de Luca, Lukas Lihotzki, Luke Hamburg, luzpaz, Majed Abdulaziz, Marc Laporte, Marcel Meyer, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Martchus, Mateusz Naściszewski, Mateusz Ż, mathias4833, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, mattn, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maximilian, Maxwell G, Michael Jephcote, Michael Rienstra, Michael Wang 汪東陽, MichaIng, Migelo, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, mv1005, Nate Morrison, nf, Nicholas Rishel, Nick Busey, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, orangekame3, otbutz, overkill, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Paul Donald, Pawel Palenica, perewa, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phani Rithvij, Phil Davis, Philippe Schommers, Phill Luby, Piotr Bejda, polyfloyd, Prathik P Kulkarni, pullmerge, Quentin Hibon, Rahmi Pruitt, RealCharlesChia, red_led, Robert Carosi, Roberto Santalla, Robin Schoonover, Roman Zaynetdinov, rubenbe, Ruslan Yevdokymov, Ryan Qian, Ryan Sullivan, Sacheendra Talluri, Scott Klupfel, sec65, Sergey Mishin, Sertonix, Severin von Wnuck-Lipinski, Shaarad Dalvi, Shivam Kumar, Simon Mwepu, Simon Pickup, Sly_tom_cat, Sonu Kumar Saw, Stefan Kuntz, Steven Eckhoff, Suhas Gundimeda, Sven Bachmann, Sébastien WENSKE, Tao, Taylor Khan, Terrance, TheCreeper, Thomas, Thomas Hipp, Tim Abell, Tim Howes, Tobias Frölich, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tully Robinson, Tyler Brazier, Tyler Kropp, Umer-Azaz, Unrud, Val Markovic, vapatel2, Veeti Paananen, Victor Buinsky, Vik, Vil Brekin, villekalliomaki, Vladimir Rusinov, vvaswani, wangguoliang, WangXi, Will Rouesnel, William A. Kennington III, wouter bolsterlee, xarx00, Xavier O., xjtdy888, Yannic A., yparitcher, 佛跳墙, 落心 +Jakob Borg, Audrius Butkevicius, Simon Frei, Tomasz Wilczyński, Alexander Graf, Alexandre Viau, Anderson Mesquita, André Colomb, Antony Male, Ben Schulz, bt90, Caleb Callaway, Daniel Harte, Emil Lundberg, Eric P, Evgeny Kuznetsov, greatroar, Lars K.W. Gohlke, Lode Hoste, Marcus B Spencer, Michael Ploujnikov, Ross Smith II, Stefan Tatschner, Tommy van der Vorst, Wulf Weich, Adam Piggott, Adel Qalieh, Aleksey Vasenev, Alessandro G., Alex Ionescu, Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Andreas Sommer, andresvia, Andrew Rabert, Andrey D, andyleap, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, ardevd, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Ashish Bhate, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Beat Reichenbach, Ben Norcombe, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benno Fünfstück, Benny Ng, boomsquared, Boqin Qin, Boris Rybalkin, Brendan Long, Catfriend1, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Christian Kujau, Christian Prescott, chucic, cjc7373, Colin Kennedy, Cromefire_, cui, Cyprien Devillez, d-volution, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Daniel Padrta, Daniil Gentili, Darshil Chanpura, dashangcun, David Rimmer, DeflateAwning, Denis A., Dennis Wilson, derekriemer, DerRockWolf, desbma, Devon G. Redekopp, digital, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, domain, Domenic Horner, Dominik Heidler, Elias, Elias Jarlebring, Elliot Huffman, Emil Hessman, Eng Zer Jun, entity0xfe, Epifeny, epifeny, Eric Lesiuta, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, georgespatton, ghjklw, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, guangwu, gudvinr, Gusted, Han Boetes, HansK-p, Harrison Jones, Hazem Krimi, Heiko Zuerker, Hireworks, Hugo Locurcio, Iain Barnett, Ian Johnson, ignacy123, Iskander Sharipov, Jaakko Hannikainen, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jaspitta, Jaya Chithra, Jaya Kumar, Jeffery To, jelle van der Waa, Jens Diemer, Jochen Voss, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jose Manuel Delicado, JRNitre, jtagcat, Julian Lehrhuber, Jörg Thalheim, Jędrzej Kula, Kapil Sareen, Karol Różycki, Kebin Liu, Keith Harrison, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., klemens, Kurt Fitzner, kylosus, Lars Lehtonen, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, LSmithx2, Luiz Angelo Daros de Luca, Lukas Lihotzki, Luke Hamburg, luzpaz, Majed Abdulaziz, Marc Laporte, Marcel Meyer, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Martchus, Mateusz Naściszewski, Mateusz Ż, mathias4833, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, mattn, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maximilian, Maxwell G, Michael Jephcote, Michael Rienstra, Michael Wang 汪東陽, MichaIng, Migelo, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, mv1005, Nate Morrison, nf, Nicholas Rishel, Nick Busey, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, orangekame3, otbutz, overkill, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Paul Donald, Pawel Palenica, perewa, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phani Rithvij, Phil Davis, Philippe Schommers, Phill Luby, Piotr Bejda, polyfloyd, Prathik P Kulkarni, pullmerge, Quentin Hibon, Rahmi Pruitt, RealCharlesChia, red_led, Robert Carosi, Roberto Santalla, Robin Schoonover, Roman Zaynetdinov, rubenbe, Ruslan Yevdokymov, Ryan Qian, Ryan Sullivan, Sacheendra Talluri, Scott Klupfel, sec65, Sergey Mishin, Sertonix, Severin von Wnuck-Lipinski, Shaarad Dalvi, Shablone, Shivam Kumar, Simon Mwepu, Simon Pickup, Sly_tom_cat, Sonu Kumar Saw, Stefan Kuntz, Steven Eckhoff, Suhas Gundimeda, Sven Bachmann, Sébastien WENSKE, Tao, Taylor Khan, Terrance, TheCreeper, Thomas, Thomas Hipp, Tim Abell, Tim Howes, Tobias Frölich, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tully Robinson, Tyler Brazier, Tyler Kropp, Umer-Azaz, Unrud, Val Markovic, vapatel2, Veeti Paananen, Victor Buinsky, Vik, Vil Brekin, villekalliomaki, Vladimir Rusinov, vvaswani, wangguoliang, WangXi, Will Rouesnel, William A. Kennington III, wouter bolsterlee, xarx00, Xavier O., xjtdy888, Yannic A., yparitcher, 佛跳墙, 落心
diff --git a/gui/default/syncthing/core/syncthingController.js b/gui/default/syncthing/core/syncthingController.js index 43dd76c3c4a..f8b38806543 100644 --- a/gui/default/syncthing/core/syncthingController.js +++ b/gui/default/syncthing/core/syncthingController.js @@ -2997,6 +2997,9 @@ angular.module('syncthing.core') $scope.restoreVersions.tree = $("#restoreTree").fancytree({ extensions: ["table", "filter", "glyph"], quicksearch: true, + // Node titles are remote-controlled file/path + // components; render them as text, not HTML. + escapeTitles: true, filter: { hideExpanders: true, mode: "hide" diff --git a/internal/db/interface.go b/internal/db/interface.go index 980e1287957..ed15acc943a 100644 --- a/internal/db/interface.go +++ b/internal/db/interface.go @@ -79,6 +79,7 @@ type DB interface { // Cleanup DropAllFiles(folder string, device protocol.DeviceID) error + DropFolderDevice(folder string, device protocol.DeviceID) error DropDevice(device protocol.DeviceID) error DropFilesNamed(folder string, device protocol.DeviceID, names []string) error DropFolder(folder string) error diff --git a/internal/db/metrics.go b/internal/db/metrics.go index c9565eb204b..8c8fe8f2618 100644 --- a/internal/db/metrics.go +++ b/internal/db/metrics.go @@ -128,6 +128,11 @@ func (m metricsDB) DropAllFiles(folder string, device protocol.DeviceID) error { return m.DB.DropAllFiles(folder, device) } +func (m metricsDB) DropFolderDevice(folder string, device protocol.DeviceID) error { + defer m.account(folder, "DropFolderDevice")() + return m.DB.DropFolderDevice(folder, device) +} + func (m metricsDB) DropDevice(device protocol.DeviceID) error { defer m.account("-", "DropDevice")() return m.DB.DropDevice(device) diff --git a/internal/db/sqlite/db_folderdb.go b/internal/db/sqlite/db_folderdb.go index c520580c577..97039b39e51 100644 --- a/internal/db/sqlite/db_folderdb.go +++ b/internal/db/sqlite/db_folderdb.go @@ -255,6 +255,17 @@ func (s *DB) DropAllFiles(folder string, device protocol.DeviceID) error { return fdb.DropAllFiles(device) } +func (s *DB) DropFolderDevice(folder string, device protocol.DeviceID) error { + fdb, err := s.getFolderDB(folder, false) + if errors.Is(err, errNoSuchFolder) { + return nil + } + if err != nil { + return err + } + return fdb.DropDevice(device) +} + func (s *DB) DropFilesNamed(folder string, device protocol.DeviceID, names []string) error { fdb, err := s.getFolderDB(folder, false) if errors.Is(err, errNoSuchFolder) { diff --git a/internal/db/sqlite/db_test.go b/internal/db/sqlite/db_test.go index 8406b12e780..bc85ae7e79d 100644 --- a/internal/db/sqlite/db_test.go +++ b/internal/db/sqlite/db_test.go @@ -798,6 +798,13 @@ func TestDropAllFiles(t *testing.T) { t.Fatal(err) } + // The sequence is non-zero before the drop + if seq, err := db.GetDeviceSequence("a", protocol.DeviceID{1}); err != nil { + t.Fatal(err) + } else if seq == 0 { + t.Error("expected non-zero sequence before drop") + } + // Drop folder A if err := db.DropAllFiles("a", protocol.DeviceID{1}); err != nil { t.Fatal(err) @@ -825,6 +832,20 @@ func TestDropAllFiles(t *testing.T) { t.Error("expected count to be two") } + // The device sequence for the dropped folder is reset to zero. + if seq, err := db.GetDeviceSequence("a", protocol.DeviceID{1}); err != nil { + t.Fatal(err) + } else if seq != 0 { + t.Log(seq) + t.Error("expected sequence to be reset to zero after DropAllFiles") + } + // Sequence for the untouched folder is unaffected. + if seq, err := db.GetDeviceSequence("b", protocol.DeviceID{1}); err != nil { + t.Fatal(err) + } else if seq == 0 { + t.Error("expected non-zero sequence for untouched folder") + } + // Drop things that don't exist if err := db.DropAllFiles("a", protocol.DeviceID{99}); err != nil { t.Fatal(err) @@ -837,6 +858,67 @@ func TestDropAllFiles(t *testing.T) { } } +func TestDropFolderDevice(t *testing.T) { + db, err := Open(t.TempDir()) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + if err := db.Close(); err != nil { + t.Fatal(err) + } + }) + + // Files from device 1 in folder a + err = db.Update("a", protocol.DeviceID{1}, []protocol.FileInfo{ + genFile("test1", 1, 101), + genFile("test2", 2, 102), + }) + if err != nil { + t.Fatal(err) + } + + // Device 1 has an index ID. + if err := db.SetIndexID("a", protocol.DeviceID{1}, protocol.IndexID(0xdeadbeef)); err != nil { + t.Fatal(err) + } + if id, err := db.GetIndexID("a", protocol.DeviceID{1}); err != nil { + t.Fatal(err) + } else if id != protocol.IndexID(0xdeadbeef) { + t.Errorf("expected index ID to be set, got %v", id) + } + + // Drop device 1 from folder a + if err := db.DropFolderDevice("a", protocol.DeviceID{1}); err != nil { + t.Fatal(err) + } + + // Files for device 1 in folder a are gone + if _, ok, err := db.GetDeviceFile("a", protocol.DeviceID{1}, "test1"); err != nil || ok { + t.Log(err, ok) + t.Error("expected device 1 file in folder A to not exist") + } + if c, err := db.CountLocal("a", protocol.DeviceID{1}); err != nil { + t.Fatal(err) + } else if c.Files != 0 { + t.Log(c) + t.Error("expected device 1 count in folder A to be zero") + } + + // The index ID for device 1 in folder A is gone. + if id, err := db.GetIndexID("a", protocol.DeviceID{1}); err != nil { + t.Fatal(err) + } else if id != 0 { + t.Errorf("expected index ID to be cleared, got %v", id) + } + if seq, err := db.GetDeviceSequence("a", protocol.DeviceID{1}); err != nil { + t.Fatal(err) + } else if seq != 0 { + t.Log(seq) + t.Error("expected sequence to be zero after DropFolderDevice") + } +} + func TestConcurrentUpdate(t *testing.T) { t.Parallel() diff --git a/internal/db/sqlite/folderdb_update.go b/internal/db/sqlite/folderdb_update.go index 1993c1bbc36..56ff3721683 100644 --- a/internal/db/sqlite/folderdb_update.go +++ b/internal/db/sqlite/folderdb_update.go @@ -235,6 +235,13 @@ func (s *folderDB) DropAllFiles(device protocol.DeviceID) error { defer tx.Rollback() //nolint:errcheck txp := &txPreparedStmts{Tx: tx} + if _, err := tx.Exec(` + UPDATE indexids SET sequence = 0 + WHERE device_idx = ? + `, deviceIdx); err != nil { + return wrap(err) + } + // Drop all the file entries result, err := tx.Exec(` diff --git a/lib/api/api.go b/lib/api/api.go index dfdfacc362f..046ad33f233 100644 --- a/lib/api/api.go +++ b/lib/api/api.go @@ -1248,7 +1248,7 @@ func (s *service) getSupportBundle(w http.ResponseWriter, r *http.Request) { zipFilePath := filepath.Join(locations.GetBaseDir(locations.ConfigBaseDir), zipFileName) // Write buffer zip to local zip file (back up) - if err := os.WriteFile(zipFilePath, zipFilesBuffer.Bytes(), 0o600); err != nil { + if err := os.WriteFile(zipFilePath, zipFilesBuffer.Bytes(), 0o666); err != nil { slog.Warn("Failed to create support bundle zip (file)", slogutil.FilePath(zipFilePath), slogutil.Error(err)) } diff --git a/lib/config/folderconfiguration.go b/lib/config/folderconfiguration.go index 10c8a2776cb..a2ed4e5aef0 100644 --- a/lib/config/folderconfiguration.go +++ b/lib/config/folderconfiguration.go @@ -168,7 +168,7 @@ func (f *FolderConfiguration) CreateMarker() error { ffs := f.Filesystem() // Create the marker as a directory - err := ffs.Mkdir(DefaultMarkerName, 0o755) + err := ffs.Mkdir(DefaultMarkerName, fs.ModePerm) if err != nil { return err } @@ -176,7 +176,7 @@ func (f *FolderConfiguration) CreateMarker() error { // Create a file inside it, reducing the risk of the marker directory // being removed by automated cleanup tools. markerFile := filepath.Join(DefaultMarkerName, f.markerFilename()) - if err := fs.WriteFile(ffs, markerFile, f.markerContents(), 0o644); err != nil { + if err := fs.WriteFile(ffs, markerFile, f.markerContents(), 0o666); err != nil { return err } @@ -246,19 +246,10 @@ func (f *FolderConfiguration) checkFilesystemPath(ffs fs.Filesystem, path string } func (f *FolderConfiguration) CreateRoot() (err error) { - // Directory permission bits. Will be filtered down to something - // sane by umask on Unixes. - permBits := fs.FileMode(0o777) - if build.IsWindows { - // Windows has no umask so we must chose a safer set of bits to - // begin with. - permBits = 0o700 - } - filesystem := f.Filesystem() if _, err = filesystem.Stat("."); fs.IsNotExist(err) { - err = filesystem.MkdirAll(".", permBits) + err = filesystem.MkdirAll(".", fs.ModePerm) } return err diff --git a/lib/config/migrations.go b/lib/config/migrations.go index 382bccfad59..d237e8a0083 100644 --- a/lib/config/migrations.go +++ b/lib/config/migrations.go @@ -18,7 +18,6 @@ import ( "sync" "github.com/syncthing/syncthing/internal/slogutil" - "github.com/syncthing/syncthing/lib/build" "github.com/syncthing/syncthing/lib/fs" "github.com/syncthing/syncthing/lib/netutil" "github.com/syncthing/syncthing/lib/upgrade" @@ -224,27 +223,20 @@ func migrateToConfigV24(cfg *Configuration) { } func migrateToConfigV23(cfg *Configuration) { - permBits := fs.FileMode(0o777) - if build.IsWindows { - // Windows has no umask so we must chose a safer set of bits to - // begin with. - permBits = 0o700 - } - // Upgrade code remains hardcoded for .stfolder despite configurable // marker name in later versions. for i := range cfg.Folders { - fs := cfg.Folders[i].Filesystem() + ffs := cfg.Folders[i].Filesystem() // Invalid config posted, or tests. - if fs == nil { + if ffs == nil { continue } - if stat, err := fs.Stat(DefaultMarkerName); err == nil && !stat.IsDir() { - err = fs.Remove(DefaultMarkerName) + if stat, err := ffs.Stat(DefaultMarkerName); err == nil && !stat.IsDir() { + err = ffs.Remove(DefaultMarkerName) if err == nil { - err = fs.Mkdir(DefaultMarkerName, permBits) - fs.Hide(DefaultMarkerName) // ignore error + err = ffs.Mkdir(DefaultMarkerName, fs.ModePerm) + ffs.Hide(DefaultMarkerName) // ignore error } if err != nil { slog.Warn("Failed to upgrade folder marker", slogutil.Error(err)) diff --git a/lib/connections/service.go b/lib/connections/service.go index 3c2d44f101f..0cf96956f01 100644 --- a/lib/connections/service.go +++ b/lib/connections/service.go @@ -827,6 +827,11 @@ func (s *service) logListenAddressesChangedEvent(l ListenerAddresses) { func (s *service) CommitConfiguration(from, to config.Configuration) bool { newDevices := make(map[protocol.DeviceID]bool, len(to.Devices)) for _, dev := range to.Devices { + if dev.DeviceID == s.myID { + // Do not report connection metrics for ourselves + continue + } + newDevices[dev.DeviceID] = true registerDeviceMetrics(dev.DeviceID.String()) } diff --git a/lib/fs/basicfs.go b/lib/fs/basicfs.go index d5a01184f41..cf40f6fc813 100644 --- a/lib/fs/basicfs.go +++ b/lib/fs/basicfs.go @@ -174,7 +174,7 @@ func (f *BasicFilesystem) MkdirAll(path string, perm FileMode) error { return err } - return f.mkdirAll(path, os.FileMode(perm)) + return os.MkdirAll(path, os.FileMode(perm)) } func (f *BasicFilesystem) Lstat(name string) (FileInfo, error) { diff --git a/lib/fs/basicfs_unix.go b/lib/fs/basicfs_unix.go index c60e67574f1..dc0f963ce51 100644 --- a/lib/fs/basicfs_unix.go +++ b/lib/fs/basicfs_unix.go @@ -32,10 +32,6 @@ func (f *BasicFilesystem) ReadSymlink(name string) (string, error) { return os.Readlink(name) } -func (*BasicFilesystem) mkdirAll(path string, perm os.FileMode) error { - return os.MkdirAll(path, perm) -} - // Unhide is a noop on unix, as unhiding files requires renaming them. // We still check that the relative path does not try to escape the root func (f *BasicFilesystem) Unhide(name string) error { diff --git a/lib/fs/basicfs_windows.go b/lib/fs/basicfs_windows.go index d1b8d88c2bd..34c3bb8601d 100644 --- a/lib/fs/basicfs_windows.go +++ b/lib/fs/basicfs_windows.go @@ -31,57 +31,6 @@ func (BasicFilesystem) CreateSymlink(target, name string) error { return errNotSupported } -// Required due to https://github.com/golang/go/issues/10900 -func (f *BasicFilesystem) mkdirAll(path string, perm os.FileMode) error { - // Fast path: if we can tell whether path is a directory or file, stop with success or error. - dir, err := os.Stat(path) - if err == nil { - if dir.IsDir() { - return nil - } - return &os.PathError{ - Op: "mkdir", - Path: path, - Err: syscall.ENOTDIR, - } - } - - // Slow path: make sure parent exists and then call Mkdir for path. - i := len(path) - for i > 0 && IsPathSeparator(path[i-1]) { // Skip trailing path separator. - i-- - } - - j := i - for j > 0 && !IsPathSeparator(path[j-1]) { // Scan backward over element. - j-- - } - - if j > 1 { - // Create parent - parent := path[0 : j-1] - if parent != filepath.VolumeName(parent) { - err = f.mkdirAll(parent, perm) - if err != nil { - return err - } - } - } - - // Parent now exists; invoke Mkdir and use its result. - err = os.Mkdir(path, perm) - if err != nil { - // Handle arguments like "foo/." by - // double-checking that directory doesn't exist. - dir, err1 := os.Lstat(path) - if err1 == nil && dir.IsDir() { - return nil - } - return err - } - return nil -} - func (f *BasicFilesystem) Unhide(name string) error { name, err := f.rooted(name) if err != nil { diff --git a/lib/fs/fakefs.go b/lib/fs/fakefs.go index ef0ccd7c519..ff69dfd32b7 100644 --- a/lib/fs/fakefs.go +++ b/lib/fs/fakefs.go @@ -153,7 +153,7 @@ func newFakeFilesystem(rootURI string, _ ...Option) *fakeFS { for (files == 0 || createdFiles < files) && (maxsize == 0 || writtenData>>20 < int64(maxsize)) { dir := filepath.Join(fmt.Sprintf("%02x", rng.Intn(255)), fmt.Sprintf("%02x", rng.Intn(255))) file := fmt.Sprintf("%016x", rng.Int63()) - _ = fs.MkdirAll(dir, 0o755) + _ = fs.MkdirAll(dir, ModePerm) fd, _ := fs.Create(filepath.Join(dir, file)) createdFiles++ @@ -169,7 +169,7 @@ func newFakeFilesystem(rootURI string, _ ...Option) *fakeFS { if !nostfolder { // Also create a default folder marker for good measure - _ = fs.Mkdir(".stfolder", 0o700) + _ = fs.Mkdir(".stfolder", ModePerm) } // We only set the latency after doing the operations required to create diff --git a/lib/model/folder_sendrecv.go b/lib/model/folder_sendrecv.go index c13024f529a..b9ea673c4a4 100644 --- a/lib/model/folder_sendrecv.go +++ b/lib/model/folder_sendrecv.go @@ -701,7 +701,7 @@ func (f *sendReceiveFolder) checkParent(file string, scanChan chan<- string) boo return true } f.sl.Debug("Creating parent directory", slogutil.FilePath(file)) - if err := f.mtimefs.MkdirAll(parent, 0o755); err != nil { + if err := f.mtimefs.MkdirAll(parent, fs.ModePerm); err != nil { f.newPullError(file, fmt.Errorf("creating parent dir: %w", err)) return false } diff --git a/lib/model/model.go b/lib/model/model.go index 4c82a81eb64..8f61f0e90f6 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -371,7 +371,7 @@ func (m *model) addAndStartFolderLockedWithIgnores(cfg config.FolderConfiguratio for _, available := range devs { if _, ok := expected[available]; !ok { l.Debugln("dropping", folder, "state for", available) - _ = m.sdb.DropAllFiles(folder, available) + _ = m.sdb.DropFolderDevice(folder, available) } } @@ -1784,7 +1784,7 @@ func (m *model) handleAutoAccepts(deviceID protocol.DeviceID, folder protocol.Fo // Attempt to create it to make sure it does, now. fullPath := filepath.Join(defaultFolderCfg.Path, path) - if err := defaultPathFs.MkdirAll(path, 0o700); err != nil { + if err := defaultPathFs.MkdirAll(path, fs.ModePerm); err != nil { slog.Error("Failed to create path for auto-accepted folder", folder.LogAttr(), slogutil.FilePath(fullPath), slogutil.Error(err)) continue } diff --git a/lib/versioner/util.go b/lib/versioner/util.go index 221de5dc548..dc2e723add8 100644 --- a/lib/versioner/util.go +++ b/lib/versioner/util.go @@ -155,7 +155,7 @@ func archiveFile(method fs.CopyRangeMethod, srcFs, dstFs fs.Filesystem, filePath if err != nil { if fs.IsNotExist(err) { slog.Debug("Creating versions dir") - err := dstFs.MkdirAll(".", 0o755) + err := dstFs.MkdirAll(".", fs.ModePerm) if err != nil { return err } @@ -328,7 +328,7 @@ func restoreFile(method fs.CopyRangeMethod, src, dst fs.Filesystem, filePath str return err } - _ = dst.MkdirAll(filepath.Dir(filePath), 0o755) + _ = dst.MkdirAll(filepath.Dir(filePath), fs.ModePerm) err := osutil.RenameOrCopy(method, src, dst, sourceFile, filePath) _ = dst.Chtimes(filePath, sourceMtime, sourceMtime) return err diff --git a/man/stdiscosrv.1 b/man/stdiscosrv.1 index fedafb2b803..d7227f133d8 100644 --- a/man/stdiscosrv.1 +++ b/man/stdiscosrv.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "STDISCOSRV" "1" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "STDISCOSRV" "1" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME stdiscosrv \- Syncthing Discovery Server .SH SYNOPSIS diff --git a/man/strelaysrv.1 b/man/strelaysrv.1 index 774610cd291..7f0a4366c03 100644 --- a/man/strelaysrv.1 +++ b/man/strelaysrv.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "STRELAYSRV" "1" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "STRELAYSRV" "1" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME strelaysrv \- Syncthing Relay Server .SH SYNOPSIS diff --git a/man/syncthing-bep.7 b/man/syncthing-bep.7 index a91fce2da69..d39a80b753b 100644 --- a/man/syncthing-bep.7 +++ b/man/syncthing-bep.7 @@ -28,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-BEP" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-BEP" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-bep \- Block Exchange Protocol v1 .SH INTRODUCTION AND DEFINITIONS diff --git a/man/syncthing-config.5 b/man/syncthing-config.5 index 94c573f25b0..b54137be060 100644 --- a/man/syncthing-config.5 +++ b/man/syncthing-config.5 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-CONFIG" "5" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-CONFIG" "5" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-config \- Syncthing Configuration .SH OVERVIEW diff --git a/man/syncthing-device-ids.7 b/man/syncthing-device-ids.7 index 3c55b0bff8c..021fada6158 100644 --- a/man/syncthing-device-ids.7 +++ b/man/syncthing-device-ids.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-DEVICE-IDS" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-DEVICE-IDS" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-device-ids \- Understanding Device IDs .sp diff --git a/man/syncthing-event-api.7 b/man/syncthing-event-api.7 index eb92b1e5562..2226ffd465a 100644 --- a/man/syncthing-event-api.7 +++ b/man/syncthing-event-api.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-EVENT-API" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-EVENT-API" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-event-api \- Event API .SH DESCRIPTION diff --git a/man/syncthing-faq.7 b/man/syncthing-faq.7 index edbed7aab2b..947fcc326a1 100644 --- a/man/syncthing-faq.7 +++ b/man/syncthing-faq.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-FAQ" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-FAQ" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-faq \- Frequently Asked Questions .INDENT 0.0 diff --git a/man/syncthing-globaldisco.7 b/man/syncthing-globaldisco.7 index ef7f7ae503d..92f34e951da 100644 --- a/man/syncthing-globaldisco.7 +++ b/man/syncthing-globaldisco.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-GLOBALDISCO" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-GLOBALDISCO" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-globaldisco \- Global Discovery Protocol v3 .SH ANNOUNCEMENTS diff --git a/man/syncthing-localdisco.7 b/man/syncthing-localdisco.7 index 9f8dbd7e4ab..bfcaefa055c 100644 --- a/man/syncthing-localdisco.7 +++ b/man/syncthing-localdisco.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-LOCALDISCO" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-LOCALDISCO" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-localdisco \- Local Discovery Protocol v4 .SH MODE OF OPERATION diff --git a/man/syncthing-networking.7 b/man/syncthing-networking.7 index ccaa16f986a..db3689279fa 100644 --- a/man/syncthing-networking.7 +++ b/man/syncthing-networking.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-NETWORKING" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-NETWORKING" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-networking \- Firewall Setup .SH ROUTER SETUP diff --git a/man/syncthing-relay.7 b/man/syncthing-relay.7 index 3a2efab8dc1..024f30570d0 100644 --- a/man/syncthing-relay.7 +++ b/man/syncthing-relay.7 @@ -28,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-RELAY" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-RELAY" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-relay \- Relay Protocol v1 .SH WHAT IS A RELAY? diff --git a/man/syncthing-rest-api.7 b/man/syncthing-rest-api.7 index a4c0ef9135a..b8cc1f576f6 100644 --- a/man/syncthing-rest-api.7 +++ b/man/syncthing-rest-api.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-REST-API" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-REST-API" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-rest-api \- REST API .sp diff --git a/man/syncthing-security.7 b/man/syncthing-security.7 index 59cc2bb4ed3..937e47b9bef 100644 --- a/man/syncthing-security.7 +++ b/man/syncthing-security.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-SECURITY" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-SECURITY" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-security \- Security Principles .sp diff --git a/man/syncthing-stignore.5 b/man/syncthing-stignore.5 index 41f3f91e733..9ef14fdaeca 100644 --- a/man/syncthing-stignore.5 +++ b/man/syncthing-stignore.5 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-STIGNORE" "5" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-STIGNORE" "5" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-stignore \- Prevent files from being synchronized to other nodes .SH SYNOPSIS diff --git a/man/syncthing-versioning.7 b/man/syncthing-versioning.7 index ba883a5943e..a97da067d19 100644 --- a/man/syncthing-versioning.7 +++ b/man/syncthing-versioning.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING-VERSIONING" "7" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING-VERSIONING" "7" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing-versioning \- Keep automatic backups of deleted files by other nodes .sp diff --git a/man/syncthing.1 b/man/syncthing.1 index da3b2c7c14a..b6f459241b3 100644 --- a/man/syncthing.1 +++ b/man/syncthing.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "SYNCTHING" "1" "May 13, 2026" "v2.1.0" "Syncthing" +.TH "SYNCTHING" "1" "May 28, 2026" "v2.1.0" "Syncthing" .SH NAME syncthing \- Syncthing .SH SYNOPSIS diff --git a/script/authors.go b/script/authors.go index 23865cc1f51..cdb3fa4d153 100644 --- a/script/authors.go +++ b/script/authors.go @@ -93,7 +93,7 @@ func main() { } bs = authorsRe.ReplaceAll(bs, []byte("id=\"contributor-list\">\n"+replacement+"\n ")) - if err := os.WriteFile(htmlFile, bs, 0o644); err != nil { + if err := os.WriteFile(htmlFile, bs, 0o666); err != nil { log.Fatal(err) } diff --git a/script/copyrights.go b/script/copyrights.go index 89a78833e9e..8c2b4f37ea7 100644 --- a/script/copyrights.go +++ b/script/copyrights.go @@ -265,7 +265,7 @@ func readAll(path string) []byte { } func writeFile(path string, data string) { - err := os.WriteFile(path, []byte(data), 0o644) + err := os.WriteFile(path, []byte(data), 0o666) if err != nil { log.Fatal(err) }