Compare commits

..
25 Commits
Author SHA1 Message Date
Syncthing Release Automation 6dfa54efa6 chore(gui, man, authors): update docs, translations, and contributors 2025-03-17 03:49:35 +00:00
mathias4833andGitHub 67575e1736 fix(api): prevent tilde expansion in path suggestions (fixes #9990) (#9992)
### Purpose

Path autocompletion wasn't working when using `~` as a shortcut for the
home directory. The issue occurred because the tilde was expanded to
/home/user, which caused the suggestion to no longer match the input
(thus preventing the autocompletion from appearing in the suggestion
list).

To fix this, I replaced the custom `parentAndBase` function, which
handled path splitting in a more complex way, with `filepath.Split` from
the standard `path/filepath` package. This prevents tilde expansion
while keeping the expected behavior for path splitting.

### Testing

The issue has been tested manually on Linux.

### Screenshots


![screenshot](https://github.com/user-attachments/assets/49dd96e2-6d75-4476-946d-0dfb2ac474ef)
2025-03-15 21:06:38 +01:00
Jakob BorgandGitHub 65923fc255 fix(syncthing): don't auto upgrade to higher major on startup (#9989)
We avoided upgrading to newer major versions during normal auto upgrade
procedures, but currently not in the initial upgrade check on startup.
2025-03-13 07:59:19 +00:00
Jakob BorgandGitHub aea763868f build(deps): update dependencies (#9988) 2025-03-13 07:41:05 +00:00
Syncthing Release Automation 26b134ae7b chore(gui, man, authors): update docs, translations, and contributors 2025-03-10 03:45:18 +00:00
Emil LundbergandGitHub 893071d2ba refactor(api): extract method configMuxBuilder.postAdjustGui and add test coverage (#9979)
This is extracted from PR #9175. This deduplicates `SetPassword` calls
and makes `postAdjustGui` a single place where PR #9175 can add
another adjustment step for sanitizing changes to WebAuthn
credentials.

This also adds tests to validate that the refactored logic was not
broken.
2025-03-09 21:31:06 +01:00
Emil LundbergandGitHub 435f2d2178 refactor(api): make shutdown timeout configurable for tests (#9980)
This is extracted from PR #9175, which adds some tests that seem to
need a longer shutdown timeout when running on GitHub Actions.
2025-03-07 12:50:33 +01:00
Emil LundbergandGitHub 8461ca539b refactor(api): deduplicate HTTP test helpers and allow session cookie access (#9977)
These refactorizations were made in [PR #9175][1] to accommodate a few
new variants of authentication method and body content. On request from
reviewers, this PR extracts it as a smaller refactorization to review in
isolation.

### Purpose

This extracts a shared `httpRequest` base function from `httpGet` and
`httpPost`, which will be used in PR #9175 for new helper functions
`httpGetCsrf` (hiding all optional parameters except the CSRF token),
`httpPostCsrf` (same) and `httpPostCsrfAuth` (hiding basic auth
parameters). A `getSessionCookie` function is also extracted from
`hasSessionCookie` and will be used to test that concurrent WebAuthn
authentications result in separate sessions (indicated by different
session cookies).
2025-03-07 11:07:01 +01:00
Jakob Borg fb977dc61d build: correct API call for Weblate statistics
Something changed...
2025-03-03 08:11:29 +01:00
Jakob BorgandGitHub ee7ab4ce25 build(deps): update dependencies (#9978) 2025-03-01 21:33:13 +00:00
polyfloydandGitHub c3ce9713d9 chore(etc): remove /usr/bin prefix from Linux .desktop files (#9966)
Exec accepts just the program name and will look for it in $PATH. This
makes these files work on NixOS which does not create a /usr/bin
directory.
2025-02-28 20:59:07 +01:00
Jakob BorgandGitHub 6a147091c5 build: use Go 1.24, minimum is Go 1.23 (#9960) 2025-02-12 10:16:46 +01:00
Jakob Borg 6208c36417 fix(policy): do not require multiple maintainers for build changes 2025-02-12 09:47:09 +01:00
Syncthing Release Automation 453fd20eeb chore(gui, man, authors): update docs, translations, and contributors 2025-02-10 03:46:14 +00:00
28f0cffdb6 chore(fs): build kqueue instead of fsevents watcher on iOS (#9950)
### Purpose

On iOS, the FSEvents API for watching files (also used on macOS) is not
available, but `kqueue` is. This PR ensures `kqueue` support is built on
iOS instead of the FSEvents based watcher implementation.

Before this PR, you could already use the `kqueue` build option to force
its usage. Unfortunately `gomobile`, the tool that I use to build
Syncthing for iOS and macOS for Synctrain, does not support setting
different build flags for iOS and macOS (unless I build separately for
each, which is a bit of a hassle because XCode nonsense). I am assuming
there are good reasons to support FSEvents even though `kqueue` is also
available on macOS (but I'm not sure why?). I do know FSEvents has been
working fine for me on macOS so it seems best to use FSEvents on macOS
and kqueue on iOS.

Note that this also requires https://github.com/syncthing/notify/pull/4
to be merged in `synchting/notify` (until that is done, this PR will
fail to build on iOS due to `notify` still trying to link to `fsevents`
stuff when the `kqueue` build flag is not set).

### Testing

I compiled both `syncthing/notify` and syncthing with this PR applied,
and used that to successfully build the Synctrain iOS app, which after
this PR works fine and should follow up file changes a bit quicker.

### Screenshots

n/a

### Documentation

n/a

## Authorship

Your name and email will be added automatically to the AUTHORS file
based on the commit metadata.

---------

Co-authored-by: Jakob Borg <jakob@kastelo.net>
2025-02-07 15:40:53 +00:00
Jakob BorgandGitHub 87c16c6cf5 build(deps): update dependencies (#9951) 2025-02-07 08:44:26 +00:00
5495c98e63 refactor: using slices.Contains to simplify the code (#9918)
### Purpose

This is a [new function](https://pkg.go.dev/slices@go1.21.0#Contains)
added in the go1.21 standard library, which can make the code more
concise and easy to read.

### Testing

Describe what testing has been done, and how the reviewer can test the
change
if new tests are not included.

### Screenshots

If this is a GUI change, include screenshots of the change. If not,
please
feel free to just delete this section.

### Documentation

If this is a user visible change (including API and protocol changes),
add a link here
to the corresponding pull request on https://github.com/syncthing/docs
or describe
the documentation changes necessary.

## Authorship

Your name and email will be added automatically to the AUTHORS file
based on the commit metadata.

Signed-off-by: dashangcun <907225865@qq.com>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2025-02-07 08:21:24 +00:00
Jakob BorgandGitHub da7d5ce608 build: switch to cloud code signing for Windows (#9948)
The requirements for Windows code signing changed in 2023, so that newly
generated certificates can only be stored in hardware modules. Luckily,
I managed to snag a three year certificate before that so it hasn't
affected us so much. Now though, it does, because our cert is expiring
in March.

This changes the code signing process for Windows to use a cloud
service, Azure Trusted Signing. This appears to work equally well and
outsources the problem entirely, while also being cheaper than the
actual certificate was to begin with. 🤷

The signing entity will be Kastelo AB and not the Syncthing Foundation,
because the latter is almost impossible to get a certificate for as it's
not a normal corporate entity whose existence can be verified, etc. This
is also how it was prior to the latest certificate; it's not ideal, but
I think it's acceptable under the circumstances.
2025-02-06 10:43:23 +01:00
Syncthing Release Automation b300c297c6 chore(gui, man, authors): update docs, translations, and contributors 2025-02-03 03:45:29 +00:00
Syncthing Release Automation 124673f7a8 chore(gui, man, authors): update docs, translations, and contributors 2025-01-27 03:45:14 +00:00
Jakob BorgandGitHub 0395cf2bc0 fix(model): clarify errors on Windows user/group lookup (fixes #9929) (#9930)
Currently, this just results in a very ambiguous `setting metadata: lookup
failed` while it could report what it's looking up and why it failed
(not found, etc).
2025-01-20 09:59:05 +01:00
Syncthing Release Automation 36cd70040a chore(gui, man, authors): update docs, translations, and contributors 2025-01-20 03:45:10 +00:00
Jakob BorgandGitHub 1fbd396ffa chore(scanner): don't warn about cancelled scan (#9920)
We expect a context cancellation when a folder is restarted during a
scan.
2025-01-13 17:35:55 +00:00
Syncthing Release Automation 2834bad85e chore(gui, man, authors): update docs, translations, and contributors 2025-01-13 03:47:27 +00:00
Jakob BorgandGitHub 516f3e29e8 chore(proto): change symlinktarget to be byte sequence (fixes #9913) (#9914) 2025-01-11 17:38:29 +01:00
55 changed files with 670 additions and 374 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ on:
- infra-*
env:
GO_VERSION: "~1.23.0"
GO_VERSION: "~1.24.0"
CGO_ENABLED: "0"
BUILD_USER: docker
BUILD_HOST: github.syncthing.net
+58 -10
View File
@@ -12,7 +12,7 @@ env:
# The go version to use for builds. We set check-latest to true when
# installing, so we get the latest patch version that matches the
# expression.
GO_VERSION: "~1.23.0"
GO_VERSION: "~1.24.0"
# Optimize compatibility on the slow archictures.
GO386: softfloat
@@ -48,7 +48,7 @@ jobs:
runner: ["windows-latest", "ubuntu-latest", "macos-latest"]
# The oldest version in this list should match what we have in our go.mod.
# Variables don't seem to be supported here, or we could have done something nice.
go: ["~1.22.6", "~1.23.0"]
go: ["~1.23.0", "~1.24.0"]
runs-on: ${{ matrix.runner }}
steps:
- name: Set git to use LF
@@ -127,6 +127,7 @@ jobs:
- package-cross
- package-source
- package-debian
- package-windows
- govulncheck
steps:
- uses: actions/checkout@v4
@@ -137,8 +138,6 @@ jobs:
package-windows:
name: Package for Windows
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/release' || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/v'))
environment: release
runs-on: windows-latest
steps:
- name: Set git to use LF
@@ -188,16 +187,65 @@ jobs:
}
env:
CGO_ENABLED: "0"
CODESIGN_SIGNTOOL: ${{ secrets.CODESIGN_SIGNTOOL }}
CODESIGN_CERTIFICATE_BASE64: ${{ secrets.CODESIGN_CERTIFICATE_BASE64 }}
CODESIGN_CERTIFICATE_PASSWORD: ${{ secrets.CODESIGN_CERTIFICATE_PASSWORD }}
CODESIGN_TIMESTAMP_SERVER: ${{ secrets.CODESIGN_TIMESTAMP_SERVER }}
- name: Archive artifacts
uses: actions/upload-artifact@v4
with:
name: unsigned-packages-windows
path: "*.zip"
codesign-windows:
name: Codesign for Windows
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/release' || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/v'))
environment: release
runs-on: windows-latest
needs:
- package-windows
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: unsigned-packages-windows
path: packages
- name: Extract packages
working-directory: packages
run: |
$files = Get-ChildItem "." -Filter *.zip
foreach ($file in $files) {
7z x $file.Name
}
- name: Sign files with Trusted Signing
uses: azure/trusted-signing-action@v0.5.1
with:
azure-tenant-id: ${{ secrets.AZURE_TRUSTED_SIGNING_TENANT_ID }}
azure-client-id: ${{ secrets.AZURE_TRUSTED_SIGNING_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_TRUSTED_SIGNING_CLIENT_SECRET }}
endpoint: ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }}
trusted-signing-account-name: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT }}
certificate-profile-name: ${{ secrets.AZURE_TRUSTED_SIGNING_PROFILE }}
files-folder: ${{ github.workspace }}\packages
files-folder-filter: exe
files-folder-recurse: true
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Repackage packages
working-directory: packages
run: |
$files = Get-ChildItem "." -Filter *.zip
foreach ($file in $files) {
Remove-Item $file.Name
7z a -tzip $file.Name $file.BaseName
}
- name: Archive artifacts
uses: actions/upload-artifact@v4
with:
name: packages-windows
path: "*.zip"
path: "packages/*.zip"
#
# Linux
@@ -502,7 +550,7 @@ jobs:
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/release' || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/v'))
environment: release
needs:
- package-windows
- codesign-windows
- package-linux
- package-macos
- package-cross
-1
View File
@@ -42,7 +42,6 @@ approval_rules:
paths:
- ^[^/]+\.md
- ^\.policy\.yml
- ^\.github/
- ^LICENSE
requires:
count: 1
+3
View File
@@ -97,6 +97,7 @@ Daniel Harte (norgeous) <daniel@harte.me> <daniel@danielharte.co.uk> <norgeous@u
Daniel Martí (mvdan) <mvdan@mvdan.cc>
Daniel Padrta <64928366+danpadcz@users.noreply.github.com>
Darshil Chanpura (dtchanpura) <dtchanpura@gmail.com> <dcprime314@gmail.com>
dashangcun <907225865@qq.com>
David Rimmer (dinosore) <dinosore@dbrsoftware.co.uk>
deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
DeflateAwning <11021263+DeflateAwning@users.noreply.github.com>
@@ -229,6 +230,7 @@ Martchus <martchus@gmx.net>
Martin Polehla <p0l0us@users.noreply.github.com>
Mateusz Naściszewski (mateon1) <matin1111@wp.pl>
Mateusz Ż <thedead4fun@live.com>
mathias4833 <67101597+mathias4833@users.noreply.github.com>
Matic Potočnik <hairyfotr@gmail.com>
Matt Burke (burkemw3) <mburke@amplify.com> <burkemw3@gmail.com>
Matt Robenolt <matt@ydekproductions.com>
@@ -287,6 +289,7 @@ Philippe Schommers (filoozoom) <philippe@schommers.be>
Phill Luby (pluby) <phill.luby@newredo.com>
Pier Paolo Ramon <ramonpierre@gmail.com>
Piotr Bejda (piobpl) <piotrb10@gmail.com>
polyfloyd <polyfloyd@users.noreply.github.com>
Pramodh KP (pramodhkp) <pramodh.p@directi.com> <1507241+pramodhkp@users.noreply.github.com>
Quentin Hibon <qh.public@yahoo.com>
Rahmi Pruitt <rjpruitt16@gmail.com>
+1 -69
View File
@@ -15,7 +15,6 @@ import (
"bytes"
"compress/flate"
"compress/gzip"
"encoding/base64"
"encoding/json"
"errors"
"flag"
@@ -1345,10 +1344,7 @@ func zipFile(out string, files []archiveFile) {
}
func codesign(target target) {
switch goos {
case "windows":
windowsCodesign(target.BinaryName())
case "darwin":
if goos == "darwin" {
macosCodesign(target.BinaryName())
}
}
@@ -1372,70 +1368,6 @@ func macosCodesign(file string) {
}
}
func windowsCodesign(file string) {
st := "signtool.exe"
if path := os.Getenv("CODESIGN_SIGNTOOL"); path != "" {
st = path
}
for i, algo := range []string{"sha1", "sha256"} {
args := []string{"sign", "/fd", algo}
if f := os.Getenv("CODESIGN_CERTIFICATE_FILE"); f != "" {
args = append(args, "/f", f)
} else if b := os.Getenv("CODESIGN_CERTIFICATE_BASE64"); b != "" {
// Decode the PFX certificate from base64.
bs, err := base64.RawStdEncoding.DecodeString(b)
if err != nil {
log.Println("Codesign: signing failed: decoding base64:", err)
return
}
// Write it to a temporary file
f, err := os.CreateTemp("", "codesign-*.pfx")
if err != nil {
log.Println("Codesign: signing failed: creating temp file:", err)
return
}
_ = f.Chmod(0o600) // best effort remove other users' access
defer os.Remove(f.Name())
if _, err := f.Write(bs); err != nil {
log.Println("Codesign: signing failed: writing temp file:", err)
return
}
if err := f.Close(); err != nil {
log.Println("Codesign: signing failed: closing temp file:", err)
return
}
// Use that when signing
args = append(args, "/f", f.Name())
}
if p := os.Getenv("CODESIGN_CERTIFICATE_PASSWORD"); p != "" {
args = append(args, "/p", p)
}
if tr := os.Getenv("CODESIGN_TIMESTAMP_SERVER"); tr != "" {
switch algo {
case "sha256":
args = append(args, "/tr", tr, "/td", algo)
default:
args = append(args, "/t", tr)
}
}
if i > 0 {
args = append(args, "/as")
}
args = append(args, file)
bs, err := runError(st, args...)
if err != nil {
log.Printf("Codesign: signing failed: %v: %s", err, string(bs))
return
}
log.Println("Codesign: successfully signed", file, "using", algo)
}
}
func metalint() {
lazyRebuildAssets()
runPrint(goCmd, "test", "-run", "Metalint", "./meta")
+4
View File
@@ -830,6 +830,10 @@ func initialAutoUpgradeCheck(misc *db.NamespacedKV) (upgrade.Release, error) {
if err != nil {
return upgrade.Release{}, err
}
if upgrade.CompareVersions(release.Tag, build.Version) == upgrade.MajorNewer {
return upgrade.Release{}, errors.New("higher major version")
}
if lastVersion, ok, err := misc.String(upgradeVersionKey); err == nil && ok && lastVersion == release.Tag {
// Only check time if we try to upgrade to the same release.
if lastTime, ok, err := misc.Time(upgradeTimeKey); err == nil && ok && time.Since(lastTime) < upgradeRetryInterval {
+1 -1
View File
@@ -2,7 +2,7 @@
Name=Start Syncthing
GenericName=File synchronization
Comment=Starts the main syncthing process in the background.
Exec=/usr/bin/syncthing serve --no-browser --logfile=default
Exec=syncthing serve --no-browser --logfile=default
Icon=syncthing
Terminal=false
Type=Application
+1 -1
View File
@@ -2,7 +2,7 @@
Name=Syncthing Web UI
GenericName=File synchronization UI
Comment=Opens Syncthing's Web UI in the default browser (Syncthing must already be started).
Exec=/usr/bin/syncthing --browser-only
Exec=syncthing --browser-only
Icon=syncthing
Terminal=false
Type=Application
+21 -21
View File
@@ -1,11 +1,11 @@
module github.com/syncthing/syncthing
go 1.22.0
go 1.23.0
require (
github.com/AudriusButkevicius/recli v0.0.7-0.20220911121932-d000ce8fbf0f
github.com/alecthomas/kong v1.6.0
github.com/aws/aws-sdk-go v1.55.5
github.com/alecthomas/kong v1.9.0
github.com/aws/aws-sdk-go v1.55.6
github.com/calmh/incontainer v1.0.0
github.com/calmh/xdr v1.2.0
github.com/ccding/go-stun v0.1.5
@@ -21,31 +21,31 @@ require (
github.com/julienschmidt/httprouter v1.3.0
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/maruel/panicparse/v2 v2.4.0
github.com/maxbrunsfeld/counterfeiter/v6 v6.8.1
github.com/maxbrunsfeld/counterfeiter/v6 v6.11.2
github.com/maxmind/geoipupdate/v6 v6.1.0
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75
github.com/oschwald/geoip2-golang v1.11.0
github.com/pierrec/lz4/v4 v4.1.22
github.com/prometheus/client_golang v1.20.5
github.com/puzpuzpuz/xsync/v3 v3.4.0
github.com/quic-go/quic-go v0.48.2
github.com/prometheus/client_golang v1.21.1
github.com/puzpuzpuz/xsync/v3 v3.5.1
github.com/quic-go/quic-go v0.50.0
github.com/rabbitmq/amqp091-go v1.10.0
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
github.com/shirou/gopsutil/v4 v4.24.12
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2
github.com/shirou/gopsutil/v4 v4.25.2
github.com/syncthing/notify v0.0.0-20250207082249-f0fa8f99c2bc
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d
github.com/thejerf/suture/v4 v4.0.6
github.com/urfave/cli v1.22.16
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0
github.com/willabides/kongplete v0.4.0
go.uber.org/automaxprocs v1.6.0
golang.org/x/crypto v0.31.0
golang.org/x/net v0.33.0
golang.org/x/sys v0.28.0
golang.org/x/text v0.21.0
golang.org/x/time v0.8.0
golang.org/x/tools v0.28.0
google.golang.org/protobuf v1.36.1
golang.org/x/crypto v0.36.0
golang.org/x/net v0.37.0
golang.org/x/sys v0.31.0
golang.org/x/text v0.23.0
golang.org/x/time v0.11.0
golang.org/x/tools v0.31.0
google.golang.org/protobuf v1.36.5
sigs.k8s.io/yaml v1.4.0
)
@@ -57,7 +57,7 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/ebitengine/purego v0.8.1 // indirect
github.com/ebitengine/purego v0.8.2 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
@@ -80,7 +80,7 @@ require (
github.com/posener/complete v1.2.3 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.60.0 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
@@ -89,10 +89,10 @@ require (
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.9.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/mock v0.4.0 // indirect
go.uber.org/mock v0.5.0 // indirect
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/sync v0.12.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+44 -38
View File
@@ -5,14 +5,14 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/kong v1.6.0 h1:mwOzbdMR7uv2vul9J0FU3GYxE7ls/iX1ieMg5WIM6gE=
github.com/alecthomas/kong v1.6.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
github.com/alecthomas/kong v1.9.0 h1:Wgg0ll5Ys7xDnpgYBuBn/wPeLGAuK0NvYmEcisJgrIs=
github.com/alecthomas/kong v1.9.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI=
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk=
github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/calmh/glob v0.0.0-20220615080505-1d823af5017b h1:Fjm4GuJ+TGMgqfGHN42IQArJb77CfD/mAwLbDUoJe6g=
@@ -41,8 +41,8 @@ github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkE
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE=
github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I=
github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
@@ -81,8 +81,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20241009165004-a3522334989c h1:NDovD0SMpBYXlE1zJmS1q55vWB/fUQBcPAqAboZSccA=
github.com/google/pprof v0.0.0-20241009165004-a3522334989c/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
@@ -143,8 +144,8 @@ github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMD
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/maruel/panicparse/v2 v2.4.0 h1:yQKMIbQ0DKfinzVkTkcUzQyQ60UCiNnYfR7PWwTs2VI=
github.com/maruel/panicparse/v2 v2.4.0/go.mod h1:nOY2OKe8csO3F3SA5+hsxot05JLgukrF54B9x88fVp4=
github.com/maxbrunsfeld/counterfeiter/v6 v6.8.1 h1:NicmruxkeqHjDv03SfSxqmaLuisddudfP3h5wdXFbhM=
github.com/maxbrunsfeld/counterfeiter/v6 v6.8.1/go.mod h1:eyp4DdUJAKkr9tvxR3jWhw2mDK7CWABMG5r9uyaKC7I=
github.com/maxbrunsfeld/counterfeiter/v6 v6.11.2 h1:yVCLo4+ACVroOEr4iFU1iH46Ldlzz2rTuu18Ra7M8sU=
github.com/maxbrunsfeld/counterfeiter/v6 v6.11.2/go.mod h1:VzB2VoMh1Y32/QqDfg9ZJYHj99oM4LiGtqPZydTiQSQ=
github.com/maxmind/geoipupdate/v6 v6.1.0 h1:sdtTHzzQNJlXF5+fd/EoPTucRHyMonYt/Cok8xzzfqA=
github.com/maxmind/geoipupdate/v6 v6.1.0/go.mod h1:cZYCDzfMzTY4v6dKRdV7KTB6SStxtn3yFkiJ1btTGGc=
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75 h1:cUVxyR+UfmdEAZGJ8IiKld1O0dbGotEnkMolG5hfMSY=
@@ -167,8 +168,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/oschwald/geoip2-golang v1.11.0 h1:hNENhCn1Uyzhf9PTmquXENiWS6AlxAEnBII6r8krA3w=
github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
@@ -186,18 +187,18 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA=
github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4=
github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=
github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/quic-go/quic-go v0.50.0 h1:3H/ld1pa3CYhkcc20TPIyG1bNsdhn9qZBGN3b9/UyUo=
github.com/quic-go/quic-go v0.50.0/go.mod h1:Vim6OmUvlYdwBhXP9ZVrtGmCMWa3wEqhq3NgYrI8b4E=
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
@@ -210,8 +211,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM=
github.com/shirou/gopsutil/v4 v4.24.12 h1:qvePBOk20e0IKA1QXrIIU+jmk+zEiYVVx06WjBRlZo4=
github.com/shirou/gopsutil/v4 v4.24.12/go.mod h1:DCtMPAad2XceTeIAbGyVfycbYQNBGk2P8cvDi7/VN9o=
github.com/shirou/gopsutil/v4 v4.25.2 h1:NMscG3l2CqtWFS86kj3vP7soOczqrQYIEhO/pMvvQkk=
github.com/shirou/gopsutil/v4 v4.25.2/go.mod h1:34gBYJzyqCDT11b6bMHP0XCvWeU3J61XRT7a2EmCRTA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -227,8 +228,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2 h1:F4snRP//nIuTTW9LYEzVH4HVwDG9T3M4t8y/2nqMbiY=
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2/go.mod h1:J0q59IWjLtpRIJulohwqEZvjzwOfTEPp8SVhDJl+y0Y=
github.com/syncthing/notify v0.0.0-20250207082249-f0fa8f99c2bc h1:xc3UfSFlH/X5hRw3h21RF6WXnRUYKmGRx06FEaVxfkM=
github.com/syncthing/notify v0.0.0-20250207082249-f0fa8f99c2bc/go.mod h1:J0q59IWjLtpRIJulohwqEZvjzwOfTEPp8SVhDJl+y0Y=
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs=
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48=
github.com/thejerf/suture/v4 v4.0.6 h1:QsuCEsCqb03xF9tPAsWAj8QOAJBgQI1c0VqJNaingg8=
@@ -252,8 +253,8 @@ go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -262,8 +263,9 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -272,8 +274,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -291,8 +293,9 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -301,8 +304,9 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -330,8 +334,9 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -350,10 +355,11 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
@@ -361,8 +367,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -376,8 +382,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+5 -5
View File
@@ -11,7 +11,7 @@
"Add Device": "Agregar el dispositivo",
"Add Folder": "Agregar Carpeta",
"Add Remote Device": "Añadir un dispositivo remoto",
"Add devices from the introducer to our device list, for mutually shared folders.": "Añadir dispositivos desde el introductor a nuestra lista de dispositivos, para las carpetas compartidas mutuamente.",
"Add devices from the introducer to our device list, for mutually shared folders.": "Añadir dispositivos del presentador a nuestra lista de dispositivos para las carpetas compartidas mutuamente.",
"Add filter entry": "Añadir una entrada al filtro",
"Add ignore patterns": "Agregar patrones a ignorar",
"Add new folder?": "¿Agregar una carpeta nueva?",
@@ -29,7 +29,7 @@
"Altered by ignoring deletes.": "Alterado ignorando eliminaciones.",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Un comando externo maneja las versiones. Tienes que eliminar el archivo de la carpeta compartida. Si la ruta a la aplicación contiene espacios, ésta debe estar entre comillas.",
"Anonymous Usage Reporting": "Informe anónimo de uso",
"Anonymous usage report format has changed. Would you like to move to the new format?": "El formato del informe de uso anónimo a cambiado. ¿Desearía usar el nuevo formato?",
"Anonymous usage report format has changed. Would you like to move to the new format?": "El formato del informe de uso anónimo a cambiado. ¿Le gustaría pasar al nuevo formato?",
"Applied to LAN": "Aplicado a la LAN",
"Apply": "Solicitar",
"Are you sure you want to override all remote changes?": "¿Está seguro(a) de que desea sobreescribir todos los cambios remotos?",
@@ -131,7 +131,7 @@
"Edit Device": "Editar Dispositivo",
"Edit Device Defaults": "Editar Valores Predeterminados del Dispositivo",
"Edit Folder": "Editar Carpeta",
"Edit Folder Defaults": "Editar Valores Predeterminados de la Carpeta",
"Edit Folder Defaults": "Editar Valores Predeterminados de las Carpeta",
"Editing {%path%}.": "Editando {{path}}.",
"Enable Crash Reporting": "Activar Informes de Fallos",
"Enable NAT traversal": "Permitir NAT transversal",
@@ -269,7 +269,7 @@
"No upgrades": "Sin actualizaciones",
"Not shared": "No Compartido(a)",
"Notice": "Aviso",
"Number of Connections": "Número de las conexiones",
"Number of Connections": "Número de conexiones",
"OK": "De acuerdo",
"Off": "Desactivado",
"Oldest First": "El más antiguo primero",
@@ -532,7 +532,7 @@
"deleted": "eliminado",
"deny": "denegar",
"directories": "directorios",
"file": "expediente",
"file": "fichero",
"files": "archivos",
"folder": "carpeta",
"full documentation": "Documentación completa",
+9 -9
View File
@@ -403,7 +403,7 @@
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Ang Syncthing ay Libre at Open Source na Software na nakalisensya sa MPL v2.0.",
"Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.": "Ang Syncthing ay isang continuous na file synchronization na program. Sini-synchronize nito ang mga file sa pagitan ng dalawa o higit pang mga computer sa totoong oras, ligtas na protektado mula sa prying na mata. Ang iyong data ay iyong data at nararapat kang pumili kung saan sila ilalagay, kung binabahagi ito sa third party, at kung paano ito pinapadala sa Internet.",
"Syncthing is listening on the following network addresses for connection attempts from other devices:": "Nakikinig ang Syncthing sa mga sumusunod na network address para sa mga tangka sa koneksyon mula sa ibang device:",
"Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.": "Hindi nakikinig ang Syncthing sa mga tangka sa koneksyon mula sa ibang mga device sa anumang address. Ang mga palabas na koneksyon lamang ay maaring gumana.",
"Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.": "Hindi nakikinig ang Syncthing sa mga tangka sa koneksyon mula sa ibang mga device sa anumang address. Ang mga palabas na koneksyon lamang ay maaaring gumana.",
"Syncthing is restarting.": "Nagre-restart ang Syncthing.",
"Syncthing is saving changes.": "Nagse-save ng mga pagbabago ang Syncthing.",
"Syncthing is upgrading.": "Naga-upgrade ang Syncthing.",
@@ -417,17 +417,17 @@
"The Syncthing Authors": "Ang Mga Awtor ng Syncthing",
"The Syncthing admin interface is configured to allow remote access without a password.": "Naka-configure ang Syncthing admin interface na payagan ang remote access nang walang password.",
"The aggregated statistics are publicly available at the URL below.": "Available nang publiko ang pinagsama-samang istatistika sa URL sa ibaba.",
"The cleanup interval cannot be blank.": "Hindi maaring walang laman ang pagitan ng paglinis.",
"The cleanup interval cannot be blank.": "Hindi maaaring walang laman ang pagitan ng paglinis.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Na-save na ang configuration ngunit hindi naka-activate. Kailangang mag-restart ang Syncthing para i-activate ang bagong configuration.",
"The device ID cannot be blank.": "Hindi maaring walang laman ang Device ID.",
"The device ID cannot be blank.": "Hindi maaaring walang laman ang Device ID.",
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Mahahanap ang device ID na ilalagay dito sa \"Mga Aksyon > Ipakita ang ID\" na dialog sa isa pang device. Opsyonal ang mga puwang at gitling (hindi pinapansin).",
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes, and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Araw-araw na pinapadala ang naka-encrypt na ulat sa paggamit. Ginagamit ito sa pag-track ng mga karaniwang platform, laki ng folder, at bersyon ng app. Kapag nabago ang tinakdang data ng ulat ipo-prompt kang muli ng dialog na ito.",
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Mukhang hindi angkop ang inilagay na device ID. Dapat itong 52 o 56 na character na string na binubuo ng mga titik at numero, na may mga puwang at gitling bilang opsyonal.",
"The folder ID cannot be blank.": "Hindi maaring walang laman ang folder ID.",
"The folder ID cannot be blank.": "Hindi maaaring walang laman ang folder ID.",
"The folder ID must be unique.": "Kailangang kakaiba ang folder ID.",
"The folder content on other devices will be overwritten to become identical with this device. Files not present here will be deleted on other devices.": "Io-overwrite ang nilalaman ng folder sa mga ibang device para maging magkapareho sa device na ito. Ang mga file na hindi nandito ay buburahin sa mga ibang device.",
"The folder content on this device will be overwritten to become identical with other devices. Files newly added here will be deleted.": "Io-overwrite ang nilalaman ng folder sa mga ibang device para maging magkapareho sa device na ito. Ang mga file na kamakilang dinagdag dito ay buburahin sa mga ibang device.",
"The folder path cannot be blank.": "Hindi maaring walang laman ang path ng folder.",
"The folder path cannot be blank.": "Hindi maaaring walang laman ang path ng folder.",
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "Ang mga sumusunod na pagitan ay ginagamit: sa unang oras ang isang bersyon ay pinapanatili bawat 30 segundo, sa unang araw ang isang bersyon ay pinapanatili bawat oras, sa unang 30 araw ang isang bersyon ay pinapanatili bawat araw, hanggang sa pinakamataas na edad ang isang bersyon ay pinapanatili bawat linggo.",
"The following items could not be synchronized.": "Hindi ma-synchronize ang mga sumusunod na item.",
"The following items were changed locally.": "Binago ng lokal ang mga sumusunod na item.",
@@ -436,14 +436,14 @@
"The following unexpected items were found.": "Nahanap ang mga sumusunod na hindi inaasahang item.",
"The interval must be a positive number of seconds.": "Dapat positibong numero ng segundo ang pagitan.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Ang pagitan, bilang segundo, para sa pagtakbo ng paglinis sa versions na direktoryo. Sero para i-disable ang periodical na paglinis.",
"The maximum age must be a number and cannot be blank.": "Dapat numero ang pinakamataas na edad at hindi maaring walang laman.",
"The maximum age must be a number and cannot be blank.": "Dapat numero ang pinakamataas na edad at hindi maaaring walang laman.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Ang pinakamataas na oras para panatilihin ang bersyon (bilang araw, itakda sa 0 para panatilihin ang mga bersyon magpakailanman).",
"The number of connections must be a non-negative number.": "Dapat hindi negatibong numero ang bilang ng mga koneksyon.",
"The number of days must be a number and cannot be blank.": "Dapat numero ang bilang ng araw at hindi maaring walang laman.",
"The number of days must be a number and cannot be blank.": "Dapat numero ang bilang ng araw at hindi maaaring walang laman.",
"The number of days to keep files in the trash can. Zero means forever.": "Ang bilang ng araw para panatilihin ang mga file sa basurahan. Ang sero ay ibig sabihin ay magpakailanman.",
"The number of old versions to keep, per file.": "Ang bilang ng mga lumang bersyon na dapat panatilihin, bawat file.",
"The number of versions must be a number and cannot be blank.": "Dapat numero ang bilang ng mga bersyon at hindi maaring walang laman.",
"The path cannot be blank.": "Hindi maaring walang laman ang path.",
"The number of versions must be a number and cannot be blank.": "Dapat numero ang bilang ng mga bersyon at hindi maaaring walang laman.",
"The path cannot be blank.": "Hindi maaaring walang laman ang path.",
"The rate limit is applied to the accumulated traffic of all connections to this device.": "Ina-apply ang rate limit sa naipon na traffic ng lahat ng mga koneksyon sa device na ito.",
"The rate limit must be a non-negative number (0: no limit)": "Dapat hindi negatibong numero ang rate limit (0: walang limitasyon)",
"The remote device has not accepted sharing this folder.": "Hindi tinanggap ng remote device ang pagbahagi ng folder na ito.",
+14
View File
@@ -6,6 +6,7 @@
"About": "Sobre",
"Action": "Acción",
"Actions": "Accións",
"Active filter rules": "Regras de filtrado activas",
"Add": "Engadir",
"Add Device": "Engadir dispositivo",
"Add Folder": "Engadir cartafol",
@@ -37,21 +38,26 @@
"Are you sure you want to restore {%count%} files?": "Está seguro de que desexa restaurar {{count}} ficheiros?",
"Are you sure you want to revert all local changes?": "Está seguro de que quere reverter todos os cambios locais?",
"Are you sure you want to upgrade?": "Está seguro de que desexa actualizar?",
"Authentication Required": "Autenticación Necesaria",
"Authors": "Autores",
"Auto Accept": "Aceptar automaticamente",
"Automatic Crash Reporting": "Informe Automático de Erros",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Agora a actualización automática permite escoller entre versións estables e versións candidatas.",
"Automatic upgrades": "Actualizacións automáticas",
"Automatic upgrades are always enabled for candidate releases.": "As actualizacións automáticas sempre están activadas para versións candidatas.",
"Automatically create or share folders that this device advertises at the default path.": "Crear ou compartir automaticamente os cartafoles na ruta predeterminada que este dispositivo anuncia.",
"Available debug logging facilities:": "Ferramentas de depuración dispoñibles:",
"Be careful!": "Teña coidado!",
"Body:": "Corpo:",
"Bugs": "Erros",
"Cancel": "Cancelar",
"Changelog": "Rexistro de cambios",
"Clean out after": "Limpar despois",
"Cleaning Versions": "Limpando Versións",
"Cleanup Interval": "Intervalo de Limpeza",
"Click to see full identification string and QR code.": "Faga clic para ver a cadea de identificación completa e o código QR.",
"Close": "Pechar",
"Command": "Orde",
"Comment, when used at the start of a line": "Comentar, cando se usa ao inicio dunha liña",
"Compression": "Compresión",
"Configuration Directory": "Directorio de Configuración",
@@ -69,13 +75,17 @@
"Copied!": "Copiado!",
"Copy": "Copiar",
"Copy failed! Try to select and copy manually.": "Fallou a copia! Probe a seleccionar e copiar manualmente.",
"Currently Shared With Devices": "Compartido actualmente cos dispositivos",
"Custom Range": "Rango personalizado",
"Danger!": "Perigo!",
"Database Location": "Localización da Base de Datos",
"Debugging Facilities": "Ferramentas de depuración",
"Default": "Predeterminado",
"Default Configuration": "Configuración Predeterminada",
"Default Device": "Dispositivo Predeterminado",
"Default Folder": "Cartafol Predeterminado",
"Default Ignore Patterns": "Patróns de Ignorado Predeterminados",
"Defaults": "Predeterminados",
"Delete": "Eliminar",
"Delete Unexpected Items": "Eliminar os Ítems Inesperados",
"Deleted {%file%}": "Eliminado {{file}}",
@@ -89,10 +99,14 @@
"Device Identification": "Identificación do dispositivo",
"Device Name": "Nome do dispositivo",
"Device Status": "Estado do dispositivo",
"Device is untrusted, enter encryption password": "Sen confianza no dispositivo, escribir contrasinal para cifrar",
"Device rate limits": "Límites do dispositivo",
"Device that last modified the item": "Dispositivo que modificou o elemento por última vez",
"Devices": "Dispositivos",
"Disable Crash Reporting": "Desactivar o Informe de Erros",
"Disabled": "Deshabilitado",
"Disabled periodic scanning and disabled watching for changes": "Desactivaronse o escaneo periódico e o control de cambios",
"Disabled periodic scanning and enabled watching for changes": "Desactivouse o escaneo periódico e activouse o control de cambios",
"Discard": "Descartar",
"Disconnected": "Desconectado",
"Disconnected (Inactive)": "Desconectado (Inactivo)",
+141 -27
View File
@@ -1,55 +1,169 @@
{
"A device with that ID is already added.": "כבר נוסף התקן עם המזהה הזה.",
"A negative number of days doesn't make sense.": "מספר שלילי של ימים אינו הגיוני.",
"A new major version may not be compatible with previous versions.": "ייתכן שגירסה ראשית חדשה אינה תואמת לגירסאות קודמות.",
"API Key": "מפתח API",
"About": "על אודות",
"About": "אודות",
"Action": "פעולה",
"Actions": "פעולות",
"Add": "הוספה",
"Add Device": "הוספת התקן",
"Add Folder": "הוספת תיקיה",
"Add Remote Device": "הוספת התקן מרוחק",
"Add new folder?": "להוסיף תיקיה חדשה?",
"Active filter rules": "כללי מסנן פעילים",
"Add": "הוסף",
"Add Device": "הוסף התקן",
"Add Folder": "הוסף תיקייה",
"Add Remote Device": "הוסף התקן מרוחק",
"Add devices from the introducer to our device list, for mutually shared folders.": "הוסף התקנים מהמנהיג לרשימת ההתקנים שלנו, בשביל תיקיות משותפות הדדית.",
"Add filter entry": "הוסף רשומת מסנן",
"Add ignore patterns": "הוסף דפוסי התעלמות",
"Add new folder?": "להוסיף תיקייה חדשה?",
"Address": "כתובת",
"Addresses": "כתובות",
"Advanced": "מתקדם",
"Advanced Configuration": "הגדרת תצורה מתקדמת",
"Advanced Configuration": "תצורה מתקדמת",
"All Data": "כל הנתונים",
"Allow Anonymous Usage Reporting?": "לאפשר דיווח שימוש בעילום שם?",
"All Time": "כל הזמנים",
"Allow Anonymous Usage Reporting?": "לאפשר דיווח שימוש אנונימי?",
"Allowed Networks": "רשתות מורשות",
"Alphabetic": "אלפאבתי",
"Anonymous Usage Reporting": "דיווח שימוש בעילום שם",
"Are you sure you want to restore {%count%} files?": "האם אכן ברצונך לשחזר {{count}} קבצים?",
"Are you sure you want to upgrade?": "האם אכן ברצונך לשדרג?",
"Auto Accept": "הסכמה אוטומטית",
"Automatic upgrades": "שדרוג אוטומטי",
"Alphabetic": "אלפביתי",
"Altered by ignoring deletes.": "השתנה על ידי התעלמות ממחיקות.",
"Anonymous Usage Reporting": "דיווח שימוש אנונימי",
"Anonymous usage report format has changed. Would you like to move to the new format?": "פורמט דוח שימוש אנונימי השתנה. האם ברצונך לעבור לפורמט החדש?",
"Applied to LAN": "הוחל על LAN",
"Apply": "החל",
"Are you sure you want to override all remote changes?": "האם אתה בטוח שברצונך לדרוס את כל השינויים המרוחקים?",
"Are you sure you want to permanently delete all these files?": "האם אתה בטוח שברצונך למחוק לצמיתות את כל הקבצים האלה?",
"Are you sure you want to remove device {%name%}?": "האם אתה בטוח שברצונך להסיר את ההתקן {{name}}?",
"Are you sure you want to remove folder {%label%}?": "האם אתה בטוח שברצונך להסיר את התיקייה {{label}}?",
"Are you sure you want to restore {%count%} files?": "האם אתה בטוח שברצונך לשחזר {{count}} קבצים?",
"Are you sure you want to revert all local changes?": "האם אתה בטוח שברצונך להחזיר את כל השינויים המקומיים?",
"Are you sure you want to upgrade?": "האם אתה בטוח שברצונך לשדרג?",
"Authentication Required": "נדרש אימות",
"Authors": "מחברים",
"Auto Accept": "קבל אוטומטית",
"Automatic Crash Reporting": "דיווח קריסה אוטומטי",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "שדרוג אוטומטי עכשיו מציע את הבחירה בין שחרורים יציבים ומועמדים לשחרור.",
"Automatic upgrades": "שדרוגים אוטומטיים",
"Automatic upgrades are always enabled for candidate releases.": "שדרוגים אוטומטיים תמיד מופעלים עבור מועמדים לשחרור.",
"Automatically create or share folders that this device advertises at the default path.": "צור או שתף תיקיות באופן אוטומטי שהתקן זה מפרסם בנתיב ברירת המחדל.",
"Available debug logging facilities:": "מתקני רישום דיבג זמינים:",
"Be careful!": "זהירות!",
"Bugs": "תקלות",
"Changelog": "רשימת שינויים",
"Close": "סגירה",
"Body:": "גוף:",
"Bugs": "באגים",
"Cancel": "ביטול",
"Changelog": "יומן שינויים",
"Clean out after": "נקה לאחר",
"Cleaning Versions": "ניקוי גרסאות",
"Cleanup Interval": "מרווח זמן לניקוי",
"Click to see full identification string and QR code.": "לחץ כדי לראות מחרוזת זיהוי מלאה וקוד QR.",
"Close": "סגור",
"Command": "פקודה",
"Comment, when used at the start of a line": "הערה, כאשר משתמשים בה בתחילת שורה",
"Compression": "דחיסה",
"Connection Error": קלת חיבור",
"Configuration Directory": יקיית תצורה",
"Configuration File": "קובץ תצורה",
"Configured": "מוגדר",
"Connected (Unused)": "מחובר (לא בשימוש)",
"Connection Error": "שגיאת חיבור",
"Connection Management": "ניהול חיבור",
"Connection Type": "סוג חיבור",
"Connections": "חיבורים",
"Connections via relays might be rate limited by the relay": "חיבורים דרך ממסרים עשויים להיות מוגבלים בקצב על ידי הממסר",
"Copied from elsewhere": "הועתק ממקום אחר",
"Copied from original": "הועתק מהמקור",
"Copied!": "הועתק!",
"Copy": "העתק",
"Copy failed! Try to select and copy manually.": "העתקה נכשלה! נסה לבחור ולהעתיק ידנית.",
"Currently Shared With Devices": "כרגע משותף עם התקנים",
"Custom Range": "טווח מותאם אישית",
"Danger!": "סכנה!",
"Database Location": "מיקום מסד נתונים",
"Debugging Facilities": "מתקני דיבוג",
"Default": "ברירת מחדל",
"Default Configuration": "תצורת ברירת מחדל",
"Default Device": "התקן ברירת מחדל",
"Default Folder": "תיקייה ברירת מחדל",
"Default Ignore Patterns": "דפוסי התעלמות ברירת מחדל",
"Defaults": "ברירות מחדל",
"Delete": "מחק",
"Delete Unexpected Items": "מחק פריטים בלתי צפויים",
"Deleted {%file%}": "{{file}} נמחק",
"Deselect All": "בטל את הבחירה בהכל",
"Deselect devices to stop sharing this folder with.": "בטל בחירת התקנים כדי להפסיק לשתף תיקייה זו עמם.",
"Deselect folders to stop sharing with this device.": "בטל בחירת תיקיות כדי להפסיק לשתף עם התקן זה.",
"Device": "התקן",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "התקן \"{{name}}\" ({{device}} ב-{{address}}) רוצה להתחבר. להוסיף התקן חדש?",
"Device Certificate": "תעודת התקן",
"Device ID": "מזהה התקן",
"Device Identification": "מזהה התקן",
"Device Identification": "זיהוי מכשיר",
"Device Name": "שם התקן",
"Device Status": "מצב התקן",
"Device is untrusted, enter encryption password": "התקן אינו מהימן, הזן סיסמת הצפנה",
"Device rate limits": "מגבלות קצב התקן",
"Device that last modified the item": "התקן ששינה את הפריט בפעם האחרונה",
"Devices": "התקנים",
"Disable Crash Reporting": "השבת דיווח קריסה",
"Disabled": "מושבת",
"Disabled periodic scanning and disabled watching for changes": "סריקה תקופתית הושבתה ומעקב אחר שינויים הושבת",
"Disabled periodic scanning and enabled watching for changes": "סריקה תקופתית הושבתה ומעקב אחר שינויים הופעל",
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "סריקה תקופתית הושבתה והגדרת מעקב אחר שינויים נכשלה, מנסה שוב כל דקה:",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "משבית השוואה וסנכרון של הרשאות קובץ. שימושי במערכות עם הרשאות שאינן קיימות או מותאמות אישית (למשל Android, Synology, exFAT, FAT).",
"Discard": "השלך",
"Disconnected": "מנותק",
"Disconnected (Inactive)": "מנותק (לא פעיל)",
"Disconnected (Unused)": "מנותק (לא בשימוש)",
"Discovered": "התגלה",
"Discovery": "גילוי",
"Discovery Failures": "כשלי גילוי",
"Discovery Status": "מצב גילוי",
"Dismiss": "דחה",
"Do not add it to the ignore list, so this notification may recur.": "אל תוסיף את זה לרשימת ההתעלמות, כך שהתראה זו עשויה לחזור.",
"Do not restore": "אל תשחזר",
"Do not restore all": "אל תשחזר הכל",
"Do you want to enable watching for changes for all your folders?": "האם ברצונך להפעיל מעקב אחר שינויים עבור כל התיקיות שלך?",
"Documentation": "תיעוד",
"Download Rate": "קצב הורדה",
"Edit": "עריכה",
"Edit Device": "עריכת התקן",
"Edit Folder": "עריכה תיקיה",
"Downloaded": ורד",
"Downloading": "מוריד",
"Edit": "ערוך",
"Edit Device": "ערוך התקן",
"Edit Device Defaults": "ערוך ברירות מחדל של התקן",
"Edit Folder": "ערוך תיקייה",
"Edit Folder Defaults": "ערוך ברירות מחדל של תיקייה",
"Editing {%path%}.": "עורך {{path}}.",
"Enable Crash Reporting": "הפעל דיווח קריסה",
"Enable NAT traversal": "הפעל חציית NAT",
"Enable Relaying": "הפעל ממסר",
"Enabled": "מופעל",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "הזן מספר לא שלילי (למשל, \"2.35\") ובחר יחידה. אחוזים הם כחלק מגודל הדיסק הכולל.",
"Enter a non-privileged port number (1024 - 65535).": "הזן מספר יציאה לא מיוחס (1024-65535).",
"Enter ignore patterns, one per line.": "הזן דפוסי התעלמות, אחד בכל שורה.",
"Enter up to three octal digits.": "הזן עד שלושה ספרות אוקטליות.",
"Error": "שגיאה",
"Folder": "תיקיה",
"Folder ID": "מזהה תיקיה",
"Folder Label": "כותרת תיקיה",
"Folder Path": "נתיב תיקיה",
"Folder Type": "סוג תיקיה",
"Extended Attributes": "תכונות מורחבות",
"Extended Attributes Filter": "מסנן תכונות מורחבות",
"External": "חיצוני",
"External File Versioning": "ניהול גירסאות קבצים חיצוניים",
"Failed Items": "פריטים שנכשלו",
"Failed to load file versions.": "טעינת גירסאות קבצים נכשלה.",
"Failed to load ignore patterns.": "טעינת דפוסי התעלמות נכשלה.",
"Failed to setup, retrying": "ההתקנה נכשלה, מנסה שוב",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "צפוי כשל בהתחברות לשרתי IPv6 אם אין קישוריות IPv6.",
"File Pull Order": "סדר משיכת קבצים",
"File Versioning": "ניהול גירסאות קבצים",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "הקבצים מועברים לתיקיית stversions. כאשר הם מוחלפים או נמחקים על ידי Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "הקבצים מועברים לגרסאות עם חותמת תאריך בתיקיית stversions. כאשר הם מוחלפים או נמחקים על ידי Syncthing.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "הקבצים מוגנים מפני שינויים שנעשו בהתקנים אחרים, אבל שינויים שנעשו בהתקן זה יישלחו לשאר האשכול.",
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "הקבצים מסונכרנים מהאשכול, אבל כל שינוי שנעשה מקומית לא יישלח להתקנים אחרים.",
"Filesystem Watcher Errors": "שגיאות משגיח מערכת קבצים",
"Filter by date": "סנן לפי תאריך",
"Filter by name": "סנן לפי שם",
"Folder": "תיקייה",
"Folder ID": "מזהה תיקייה",
"Folder Label": "תווית תיקייה",
"Folder Path": "נתיב תיקייה",
"Folder Status": "מצב תיקייה",
"Folder Type": "סוג תיקייה",
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "ניתן להגדיר תיקייה מסוג \"{{receiveEncrypted}}\" רק בעת הוספת תיקייה חדשה.",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "לא ניתן לשנות תיקייה מסוג \"{{receiveEncrypted}}\" לאחר הוספת התיקייה. אתה צריך להסיר את התיקייה, למחוק או לפענח את הנתונים בדיסק, ולהוסיף את התיקייה שוב.",
"Folders": "תיקיות",
"GUI": "ממשק משתמש",
"General": "כללי",
+5
View File
@@ -6,11 +6,14 @@
"About": "Apie programą",
"Action": "Veiksmas",
"Actions": "Veiksmai",
"Active filter rules": "Aktyvios filtro taisyklės",
"Add": "Pridėti",
"Add Device": "Pridėti įrenginį",
"Add Folder": "Pridėti aplanką",
"Add Remote Device": "Pridėti nuotolinį įrenginį",
"Add devices from the introducer to our device list, for mutually shared folders.": "Pridėti įrenginius iš supažindintojo į mūsų įrenginių sąrašą, siekiant abipusiškai bendrinti aplankus.",
"Add filter entry": "Pridėti filtro įrašą",
"Add ignore patterns": "Pridėti ignoravimo šablonų",
"Add new folder?": "Pridėti naują aplanką?",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Pilnas nuskaitymo iš naujo intervalas bus papildomai padidintas (60 kartų, t.y. nauja numatytoji 1 val. reikšmė). Taip pat vėliau, pasirinkę Ne, galite jį konfigūruoti rankiniu būdu kiekvienam atskiram aplankui.",
"Address": "Adresas",
@@ -45,6 +48,7 @@
"Automatically create or share folders that this device advertises at the default path.": "Automatiškai sukurti ar bendrinti aplankus, kuriuos šis įrenginys skelbia numatytajame kelyje.",
"Available debug logging facilities:": "Prieinamos derinimo registravimo priemonės:",
"Be careful!": "Būkite atsargūs!",
"Body:": "Turinys:",
"Bugs": "Klaidos",
"Cancel": "Atsisakyti",
"Changelog": "Keitinių žurnalas",
@@ -63,6 +67,7 @@
"Connection Management": "Ryšių valdymas",
"Connection Type": "Ryšio tipas",
"Connections": "Ryšiai",
"Connections via relays might be rate limited by the relay": "Ryšiai per tarpinius mazgus gali būti ribojami pagal užklausų skaičių per laiko vienetą",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Pastoviai stebėti pakeitimus dabar galima Syncthing viduje. Tai aptiks pakeitimus jūsų diske ir paleis nuskaitymą tik modifikuotuose keliuose. Pranašumas yra tas, kad pakeitimai sklis greičiau ir reikės mažiau pilnų nuskaitymų.",
"Copied from elsewhere": "Nukopijuota iš kitur",
"Copied from original": "Nukopijuota iš originalo",
+1
View File
@@ -1,2 +1,3 @@
{
"A device with that ID is already added.": "อุปกรณ์ที่เป็น ID นั้นๆ ได้ถูกเพิ่มเข้าไปแล้ว"
}
@@ -30,7 +30,7 @@
<h4 class="text-center" translate>The Syncthing Authors</h4>
<div class="row">
<div class="col-md-12" id="contributor-list">
Jakob Borg, Audrius Butkevicius, Jesse Lucas, Simon Frei, Tomasz Wilczyński, Alexander Graf, Alexandre Viau, Anderson Mesquita, André Colomb, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Emil Lundberg, Eric P, Evgeny Kuznetsov, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Wulf Weich, bt90, greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Aleksey Vasenev, Alessandro G., Alex Ionescu, Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Anatoli Babenia, Andreas Sommer, Andrew Dunham, Andrew Meyer, Andrew Rabert, Andrey D, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Beat Reichenbach, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benjamin Nater, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Catfriend1, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Chris Tonkinson, Christian Kujau, Christian Prescott, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Daniel Padrta, Darshil Chanpura, David Rimmer, DeflateAwning, Denis A., Dennis Wilson, DerRockWolf, Devon G. Redekopp, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Eng Zer Jun, Eric Lesiuta, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, Gusted, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hireworks, Hugo Locurcio, Iain Barnett, Ian Johnson, Ikko Ashimine, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jaspitta, Jauder Ho, Jaya Chithra, Jaya Kumar, Jeffery To, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jonta, Jose Manuel Delicado, Julian Lehrhuber, Jörg Thalheim, Jędrzej Kula, K.B.Dharun Krishna, Kalle Laine, Kapil Sareen, Karol Różycki, Kebin Liu, Keith Harrison, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, LSmithx2, Lars Lehtonen, Laurent Arnoud, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Lukas Lihotzki, Luke Hamburg, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Martchus, Martin Polehla, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maxime Thirouin, Maximilian, MichaIng, Michael Jephcote, Michael Rienstra, Michael Tilli, Migelo, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Naveen, Nicholas Rishel, Nick Busey, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, Otiel, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Pawel Palenica, Paweł Rozlach, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phani Rithvij, Phil Davis, Phill Luby, Pier Paolo Ramon, Piotr Bejda, Pramodh KP, Quentin Hibon, Rahmi Pruitt, Richard Hartmann, Robert Carosi, Roberto Santalla, Robin Schoonover, Roman Zaynetdinov, Ross Smith II, Ruslan Yevdokymov, Ryan Qian, Sacheendra Talluri, Scott Klupfel, Sertonix, Severin von Wnuck-Lipinski, Shaarad Dalvi, Simon Mwepu, Simon Pickup, Sly_tom_cat, Sonu Kumar Saw, Stefan Kuntz, Steven Eckhoff, Suhas Gundimeda, Sven Bachmann, Taylor Khan, Terrance, Thomas, Thomas Hipp, Tim Abell, Tim Howes, Tim Nordenfur, Tobias Frölich, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tommy Thorn, Tommy van der Vorst, Tully Robinson, Tyler Brazier, Tyler Kropp, Unrud, Veeti Paananen, Victor Buinsky, Vik, Vil Brekin, Vladimir Rusinov, WangXi, Will Rouesnel, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, chenrui, chucic, cjc7373, cui fliter, d-volution, derekriemer, desbma, diemade, digital, entity0xfe, georgespatton, ghjklw, guangwu, gudvinr, ignacy123, janost, jaseg, jelle van der Waa, jtagcat, klemens, kylosus, luchenhan, luzpaz, marco-m, maxice8, mclang, mv1005, nf, orangekame3, otbutz, overkill, perewa, red_led, rubenbe, sec65, vapatel2, villekalliomaki, wangguoliang, wouter bolsterlee, xarx00, xjtdy888, 佛跳墙, 落心
Jakob Borg, Audrius Butkevicius, Jesse Lucas, Simon Frei, Tomasz Wilczyński, Alexander Graf, Alexandre Viau, Anderson Mesquita, André Colomb, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Emil Lundberg, Eric P, Evgeny Kuznetsov, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Wulf Weich, bt90, greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Aleksey Vasenev, Alessandro G., Alex Ionescu, Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Anatoli Babenia, Andreas Sommer, Andrew Dunham, Andrew Meyer, Andrew Rabert, Andrey D, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Beat Reichenbach, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benjamin Nater, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Catfriend1, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Chris Tonkinson, Christian Kujau, Christian Prescott, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Daniel Padrta, Darshil Chanpura, David Rimmer, DeflateAwning, Denis A., Dennis Wilson, DerRockWolf, Devon G. Redekopp, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Eng Zer Jun, Eric Lesiuta, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, Gusted, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hireworks, Hugo Locurcio, Iain Barnett, Ian Johnson, Ikko Ashimine, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jaspitta, Jauder Ho, Jaya Chithra, Jaya Kumar, Jeffery To, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jonta, Jose Manuel Delicado, Julian Lehrhuber, Jörg Thalheim, Jędrzej Kula, K.B.Dharun Krishna, Kalle Laine, Kapil Sareen, Karol Różycki, Kebin Liu, Keith Harrison, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, LSmithx2, Lars Lehtonen, Laurent Arnoud, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Lukas Lihotzki, Luke Hamburg, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Martchus, Martin Polehla, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maxime Thirouin, Maximilian, MichaIng, Michael Jephcote, Michael Rienstra, Michael Tilli, Migelo, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Naveen, Nicholas Rishel, Nick Busey, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, Otiel, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Pawel Palenica, Paweł Rozlach, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phani Rithvij, Phil Davis, Phill Luby, Pier Paolo Ramon, Piotr Bejda, Pramodh KP, Quentin Hibon, Rahmi Pruitt, Richard Hartmann, Robert Carosi, Roberto Santalla, Robin Schoonover, Roman Zaynetdinov, Ross Smith II, Ruslan Yevdokymov, Ryan Qian, Sacheendra Talluri, Scott Klupfel, Sertonix, Severin von Wnuck-Lipinski, Shaarad Dalvi, Simon Mwepu, Simon Pickup, Sly_tom_cat, Sonu Kumar Saw, Stefan Kuntz, Steven Eckhoff, Suhas Gundimeda, Sven Bachmann, Taylor Khan, Terrance, Thomas, Thomas Hipp, Tim Abell, Tim Howes, Tim Nordenfur, Tobias Frölich, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tommy Thorn, Tommy van der Vorst, Tully Robinson, Tyler Brazier, Tyler Kropp, Unrud, Veeti Paananen, Victor Buinsky, Vik, Vil Brekin, Vladimir Rusinov, WangXi, Will Rouesnel, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, chenrui, chucic, cjc7373, cui fliter, d-volution, dashangcun, derekriemer, desbma, diemade, digital, entity0xfe, georgespatton, ghjklw, guangwu, gudvinr, ignacy123, janost, jaseg, jelle van der Waa, jtagcat, klemens, kylosus, luchenhan, luzpaz, marco-m, mathias4833, maxice8, mclang, mv1005, nf, orangekame3, otbutz, overkill, perewa, polyfloyd, red_led, rubenbe, sec65, vapatel2, villekalliomaki, wangguoliang, wouter bolsterlee, xarx00, xjtdy888, 佛跳墙, 落心
</div>
</div>
</div>
+4 -4
View File
@@ -877,7 +877,7 @@ type FileInfo struct {
Version *Vector `protobuf:"bytes,9,opt,name=version,proto3" json:"version,omitempty"`
Sequence int64 `protobuf:"varint,10,opt,name=sequence,proto3" json:"sequence,omitempty"`
Blocks []*BlockInfo `protobuf:"bytes,16,rep,name=blocks,proto3" json:"blocks,omitempty"`
SymlinkTarget string `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"`
SymlinkTarget []byte `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"`
BlocksHash []byte `protobuf:"bytes,18,opt,name=blocks_hash,json=blocksHash,proto3" json:"blocks_hash,omitempty"`
Encrypted []byte `protobuf:"bytes,19,opt,name=encrypted,proto3" json:"encrypted,omitempty"`
Type FileInfoType `protobuf:"varint,2,opt,name=type,proto3,enum=bep.FileInfoType" json:"type,omitempty"`
@@ -983,11 +983,11 @@ func (x *FileInfo) GetBlocks() []*BlockInfo {
return nil
}
func (x *FileInfo) GetSymlinkTarget() string {
func (x *FileInfo) GetSymlinkTarget() []byte {
if x != nil {
return x.SymlinkTarget
}
return ""
return nil
}
func (x *FileInfo) GetBlocksHash() []byte {
@@ -2047,7 +2047,7 @@ var file_bep_bep_proto_rawDesc = []byte{
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x65, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e,
0x66, 0x6f, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x79,
0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0d, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x61, 0x72, 0x67, 0x65,
0x28, 0x0c, 0x52, 0x0d, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x61, 0x72, 0x67, 0x65,
0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68,
0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x48, 0x61,
0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18,
+4 -4
View File
@@ -34,7 +34,7 @@ type FileInfoTruncated struct {
ModifiedBy uint64 `protobuf:"varint,12,opt,name=modified_by,json=modifiedBy,proto3" json:"modified_by,omitempty"`
Version *bep.Vector `protobuf:"bytes,9,opt,name=version,proto3" json:"version,omitempty"`
Sequence int64 `protobuf:"varint,10,opt,name=sequence,proto3" json:"sequence,omitempty"`
SymlinkTarget string `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"`
SymlinkTarget []byte `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"`
BlocksHash []byte `protobuf:"bytes,18,opt,name=blocks_hash,json=blocksHash,proto3" json:"blocks_hash,omitempty"`
Encrypted []byte `protobuf:"bytes,19,opt,name=encrypted,proto3" json:"encrypted,omitempty"`
Type bep.FileInfoType `protobuf:"varint,2,opt,name=type,proto3,enum=bep.FileInfoType" json:"type,omitempty"`
@@ -133,11 +133,11 @@ func (x *FileInfoTruncated) GetSequence() int64 {
return 0
}
func (x *FileInfoTruncated) GetSymlinkTarget() string {
func (x *FileInfoTruncated) GetSymlinkTarget() []byte {
if x != nil {
return x.SymlinkTarget
}
return ""
return nil
}
func (x *FileInfoTruncated) GetBlocksHash() []byte {
@@ -760,7 +760,7 @@ var file_dbproto_structs_proto_rawDesc = []byte{
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x74, 0x61, 0x72,
0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x79, 0x6d, 0x6c, 0x69,
0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x79, 0x6d, 0x6c, 0x69,
0x6e, 0x6b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62,
0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63,
+4 -23
View File
@@ -92,6 +92,7 @@ type service struct {
listenerAddr net.Addr
exitChan chan *svcutil.FatalErr
miscDB *db.NamespacedKV
shutdownTimeout time.Duration
guiErrors logger.Recorder
systemLog logger.Recorder
@@ -129,6 +130,7 @@ func New(id protocol.DeviceID, cfg config.Wrapper, assetDir, tlsDefaultCommonNam
startedOnce: make(chan struct{}),
exitChan: make(chan *svcutil.FatalErr, 1),
miscDB: miscDB,
shutdownTimeout: 100 * time.Millisecond,
}
}
@@ -451,7 +453,7 @@ func (s *service) Serve(ctx context.Context) error {
}
// Give it a moment to shut down gracefully, e.g. if we are restarting
// due to a config change through the API, let that finish successfully.
timeout, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
timeout, cancel := context.WithTimeout(context.Background(), s.shutdownTimeout)
defer cancel()
if err := srv.Shutdown(timeout); err == timeout.Err() {
srv.Close()
@@ -1762,7 +1764,7 @@ func browse(fsType fs.FilesystemType, current string) []string {
return browseRoots(fsType)
}
parent, base := parentAndBase(current)
parent, base := filepath.Split(current)
ffs := fs.NewFilesystem(fsType, parent)
files := browseFiles(ffs, base)
for i := range files {
@@ -1798,27 +1800,6 @@ func browseRoots(fsType fs.FilesystemType) []string {
return nil
}
// parentAndBase returns the parent directory and the remaining base of the
// path. The base may be empty if the path ends with a path separator.
func parentAndBase(current string) (string, string) {
search, _ := fs.ExpandTilde(current)
pathSeparator := string(fs.PathSeparator)
if strings.HasSuffix(current, pathSeparator) && !strings.HasSuffix(search, pathSeparator) {
search = search + pathSeparator
}
searchDir := filepath.Dir(search)
// The searchFile should be the last component of search, or empty if it
// ends with a path separator
var searchFile string
if !strings.HasSuffix(search, pathSeparator) {
searchFile = filepath.Base(search)
}
return searchDir, searchFile
}
func browseFiles(ffs fs.Filesystem, search string) []string {
subdirectories, _ := ffs.DirNames(".")
pathSeparator := string(fs.PathSeparator)
+170 -25
View File
@@ -492,13 +492,18 @@ func testHTTPRequest(t *testing.T, baseURL string, tc httpTestCase, apikey strin
}
}
func hasSessionCookie(cookies []*http.Cookie) bool {
func getSessionCookie(cookies []*http.Cookie) (*http.Cookie, bool) {
for _, cookie := range cookies {
if cookie.MaxAge >= 0 && strings.HasPrefix(cookie.Name, "sessionid") {
return true
return cookie, true
}
}
return false
return nil, false
}
func hasSessionCookie(cookies []*http.Cookie) bool {
_, ok := getSessionCookie(cookies)
return ok
}
func hasDeleteSessionCookie(cookies []*http.Cookie) bool {
@@ -510,11 +515,19 @@ func hasDeleteSessionCookie(cookies []*http.Cookie) bool {
return false
}
func httpGet(url string, basicAuthUsername string, basicAuthPassword string, xapikeyHeader string, authorizationBearer string, cookies []*http.Cookie, t *testing.T) *http.Response {
req, err := http.NewRequest("GET", url, nil)
for _, cookie := range cookies {
req.AddCookie(cookie)
func httpRequest(method string, url string, body any, basicAuthUsername, basicAuthPassword, xapikeyHeader, authorizationBearer, csrfTokenName, csrfTokenValue string, cookies []*http.Cookie, t *testing.T) *http.Response {
t.Helper()
var bodyReader io.Reader = nil
if body != nil {
bodyBytes, err := json.Marshal(body)
if err != nil {
t.Fatal(err)
}
bodyReader = bytes.NewReader(bodyBytes)
}
req, err := http.NewRequest(method, url, bodyReader)
if err != nil {
t.Fatal(err)
}
@@ -531,30 +544,16 @@ func httpGet(url string, basicAuthUsername string, basicAuthPassword string, xap
req.Header.Set("Authorization", "Bearer "+authorizationBearer)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
return resp
}
func httpPost(url string, body map[string]string, cookies []*http.Cookie, t *testing.T) *http.Response {
bodyBytes, err := json.Marshal(body)
if err != nil {
t.Fatal(err)
}
req, err := http.NewRequest("POST", url, bytes.NewReader(bodyBytes))
if err != nil {
t.Fatal(err)
if csrfTokenName != "" && csrfTokenValue != "" {
req.Header.Set("X-"+csrfTokenName, csrfTokenValue)
}
for _, cookie := range cookies {
req.AddCookie(cookie)
}
resp, err := http.DefaultClient.Do(req)
client := http.Client{Timeout: 15 * time.Second}
resp, err := client.Do(req)
if err != nil {
t.Fatal(err)
}
@@ -562,18 +561,31 @@ func httpPost(url string, body map[string]string, cookies []*http.Cookie, t *tes
return resp
}
func httpGet(url string, basicAuthUsername, basicAuthPassword, xapikeyHeader, authorizationBearer string, cookies []*http.Cookie, t *testing.T) *http.Response {
t.Helper()
return httpRequest(http.MethodGet, url, nil, basicAuthUsername, basicAuthPassword, xapikeyHeader, authorizationBearer, "", "", cookies, t)
}
func httpPost(url string, body map[string]string, cookies []*http.Cookie, t *testing.T) *http.Response {
t.Helper()
return httpRequest(http.MethodPost, url, body, "", "", "", "", "", "", cookies, t)
}
func TestHTTPLogin(t *testing.T) {
t.Parallel()
httpGetBasicAuth := func(url string, username string, password string) *http.Response {
t.Helper()
return httpGet(url, username, password, "", "", nil, t)
}
httpGetXapikey := func(url string, xapikeyHeader string) *http.Response {
t.Helper()
return httpGet(url, "", "", xapikeyHeader, "", nil, t)
}
httpGetAuthorizationBearer := func(url string, bearer string) *http.Response {
t.Helper()
return httpGet(url, "", "", "", bearer, nil, t)
}
@@ -739,6 +751,129 @@ func TestHTTPLogin(t *testing.T) {
testWith(false, http.StatusOK, http.StatusOK, "/")
testWith(false, http.StatusOK, http.StatusForbidden, "/meta.js")
testWith(false, http.StatusNotFound, http.StatusForbidden, "/any-path/that/does/nooooooot/match-any/noauth-pattern")
t.Run("Password change invalidates old and enables new password", func(t *testing.T) {
t.Parallel()
// This test needs a longer-than-default shutdown timeout to finish saving
// config changes when running on GitHub Actions
shutdownTimeout := time.Second
initConfig := func(password string, t *testing.T) config.Wrapper {
gui := config.GUIConfiguration{
RawAddress: "127.0.0.1:0",
APIKey: testAPIKey,
User: "user",
}
if err := gui.SetPassword(password); err != nil {
t.Fatal(err, "Failed to set initial password")
}
cfg := config.Configuration{
GUI: gui,
}
tmpFile, err := os.CreateTemp("", "syncthing-testConfig-Password-*")
if err != nil {
t.Fatal(err, "Failed to create tmpfile for test")
}
w := config.Wrap(tmpFile.Name(), cfg, protocol.LocalDeviceID, events.NoopLogger)
tmpFile.Close()
cfgCtx, cfgCancel := context.WithCancel(context.Background())
go w.Serve(cfgCtx)
t.Cleanup(func() {
os.Remove(tmpFile.Name())
cfgCancel()
})
return w
}
initialPassword := "Asdf123!"
newPassword := "123!asdF"
t.Run("when done via /rest/config", func(t *testing.T) {
t.Parallel()
w := initConfig(initialPassword, t)
{
baseURL, cancel, err := startHTTPWithShutdownTimeout(w, shutdownTimeout)
cfgPath := baseURL + "/rest/config"
path := baseURL + "/meta.js"
t.Cleanup(cancel)
if err != nil {
t.Fatal(err)
}
resp := httpGetBasicAuth(path, "user", initialPassword)
if resp.StatusCode != http.StatusOK {
t.Fatalf("Unexpected non-200 return code %d for auth with initial password", resp.StatusCode)
}
cfg := w.RawCopy()
cfg.GUI.Password = newPassword
httpRequest(http.MethodPut, cfgPath, cfg, "", "", testAPIKey, "", "", "", nil, t)
}
{
baseURL, cancel, err := startHTTP(w)
path := baseURL + "/meta.js"
t.Cleanup(cancel)
if err != nil {
t.Fatal(err)
}
resp := httpGetBasicAuth(path, "user", initialPassword)
if resp.StatusCode != http.StatusForbidden {
t.Errorf("Unexpected non-403 return code %d for request authed with old password", resp.StatusCode)
}
resp2 := httpGetBasicAuth(path, "user", newPassword)
if resp2.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for request authed with new password", resp2.StatusCode)
}
}
})
t.Run("when done via /rest/config/gui", func(t *testing.T) {
t.Parallel()
w := initConfig(initialPassword, t)
{
baseURL, cancel, err := startHTTPWithShutdownTimeout(w, shutdownTimeout)
cfgPath := baseURL + "/rest/config/gui"
path := baseURL + "/meta.js"
t.Cleanup(cancel)
if err != nil {
t.Fatal(err)
}
resp := httpGetBasicAuth(path, "user", initialPassword)
if resp.StatusCode != http.StatusOK {
t.Fatalf("Unexpected non-200 return code %d for auth with initial password", resp.StatusCode)
}
cfg := w.RawCopy()
cfg.GUI.Password = newPassword
httpRequest(http.MethodPut, cfgPath, cfg.GUI, "", "", testAPIKey, "", "", "", nil, t)
}
{
baseURL, cancel, err := startHTTP(w)
path := baseURL + "/meta.js"
t.Cleanup(cancel)
if err != nil {
t.Fatal(err)
}
resp := httpGetBasicAuth(path, "user", initialPassword)
if resp.StatusCode != http.StatusForbidden {
t.Errorf("Unexpected non-403 return code %d for request authed with old password", resp.StatusCode)
}
resp2 := httpGetBasicAuth(path, "user", newPassword)
if resp2.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for request authed with new password", resp2.StatusCode)
}
}
})
})
}
func TestHtmlFormLogin(t *testing.T) {
@@ -761,10 +896,12 @@ func TestHtmlFormLogin(t *testing.T) {
resourceUrl404 := baseURL + "/any-path/that/does/nooooooot/match-any/noauth-pattern"
performLogin := func(username string, password string) *http.Response {
t.Helper()
return httpPost(loginUrl, map[string]string{"username": username, "password": password}, nil, t)
}
performResourceRequest := func(url string, cookies []*http.Cookie) *http.Response {
t.Helper()
return httpGet(url, "", "", "", "", cookies, t)
}
@@ -923,6 +1060,10 @@ func TestApiCache(t *testing.T) {
}
func startHTTP(cfg config.Wrapper) (string, context.CancelFunc, error) {
return startHTTPWithShutdownTimeout(cfg, 0)
}
func startHTTPWithShutdownTimeout(cfg config.Wrapper, shutdownTimeout time.Duration) (string, context.CancelFunc, error) {
m := new(modelmocks.Model)
assetDir := "../../gui"
eventSub := new(eventmocks.BufferedSubscription)
@@ -950,6 +1091,10 @@ func startHTTP(cfg config.Wrapper) (string, context.CancelFunc, error) {
svc := New(protocol.LocalDeviceID, cfg, assetDir, "syncthing", m, eventSub, diskEventSub, events.NoopLogger, discoverer, connections, urService, mockedSummary, errorLog, systemLog, false, kdb).(*service)
svc.started = addrChan
if shutdownTimeout > 0*time.Millisecond {
svc.shutdownTimeout = shutdownTimeout
}
// Actually start the API service
supervisor := suture.New("API test", suture.Spec{
PassThroughPanics: true,
+18 -15
View File
@@ -318,13 +318,10 @@ func (c *configMuxBuilder) adjustConfig(w http.ResponseWriter, r *http.Request)
var errMsg string
var status int
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
if to.GUI.Password != cfg.GUI.Password {
if err := to.GUI.SetPassword(to.GUI.Password); err != nil {
l.Warnln("hashing password:", err)
errMsg = err.Error()
status = http.StatusInternalServerError
return
}
if err := c.postAdjustGui(&cfg.GUI, &to.GUI); err != nil {
errMsg = err.Error()
status = http.StatusInternalServerError
return
}
*cfg = to
})
@@ -391,7 +388,6 @@ func (c *configMuxBuilder) adjustOptions(w http.ResponseWriter, r *http.Request,
}
func (c *configMuxBuilder) adjustGUI(w http.ResponseWriter, r *http.Request, gui config.GUIConfiguration) {
oldPassword := gui.Password
err := unmarshalTo(r.Body, &gui)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@@ -400,13 +396,10 @@ func (c *configMuxBuilder) adjustGUI(w http.ResponseWriter, r *http.Request, gui
var errMsg string
var status int
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
if gui.Password != oldPassword {
if err := gui.SetPassword(gui.Password); err != nil {
l.Warnln("hashing password:", err)
errMsg = err.Error()
status = http.StatusInternalServerError
return
}
if err := c.postAdjustGui(&cfg.GUI, &gui); err != nil {
errMsg = err.Error()
status = http.StatusInternalServerError
return
}
cfg.GUI = gui
})
@@ -419,6 +412,16 @@ func (c *configMuxBuilder) adjustGUI(w http.ResponseWriter, r *http.Request, gui
c.finish(w, waiter)
}
func (c *configMuxBuilder) postAdjustGui(from *config.GUIConfiguration, to *config.GUIConfiguration) error {
if to.Password != from.Password {
if err := to.SetPassword(to.Password); err != nil {
l.Warnln("hashing password:", err)
return err
}
}
return nil
}
func (c *configMuxBuilder) adjustLDAP(w http.ResponseWriter, r *http.Request, ldap config.LDAPConfiguration) {
if err := unmarshalTo(r.Body, &ldap); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
+2 -7
View File
@@ -9,6 +9,7 @@ package config
import (
"fmt"
"runtime"
"slices"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/rand"
@@ -268,13 +269,7 @@ func (opts OptionsConfiguration) AutoUpgradeEnabled() bool {
}
func (opts OptionsConfiguration) FeatureFlag(name string) bool {
for _, flag := range opts.FeatureFlags {
if flag == name {
return true
}
}
return false
return slices.Contains(opts.FeatureFlags, name)
}
// LowestConnectionLimit is the lower of ConnectionLimitEnough or
+1 -2
View File
@@ -4,12 +4,11 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//go:build !(solaris && !cgo) && !(darwin && !cgo) && !(darwin && kqueue) && !(android && amd64) && !ios
//go:build !(solaris && !cgo) && !(darwin && !cgo) && !(darwin && kqueue) && !(android && amd64)
// +build !solaris cgo
// +build !darwin cgo
// +build !darwin !kqueue
// +build !android !amd64
// +build !ios
package fs
+2 -2
View File
@@ -4,8 +4,8 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//go:build dragonfly || freebsd || netbsd || openbsd
// +build dragonfly freebsd netbsd openbsd
//go:build dragonfly || freebsd || netbsd || openbsd || ios || kqueue
// +build dragonfly freebsd netbsd openbsd ios kqueue
package fs
+2 -2
View File
@@ -4,8 +4,8 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//go:build !dragonfly && !freebsd && !netbsd && !openbsd
// +build !dragonfly,!freebsd,!netbsd,!openbsd
//go:build !dragonfly && !freebsd && !netbsd && !openbsd && !kqueue && !ios
// +build !dragonfly,!freebsd,!netbsd,!openbsd,!kqueue,!ios
package fs
+2 -2
View File
@@ -4,8 +4,8 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//go:build (solaris && !cgo) || (darwin && !cgo) || (android && amd64) || ios || (darwin && kqueue)
// +build solaris,!cgo darwin,!cgo android,amd64 ios darwin,kqueue
//go:build (solaris && !cgo) || (darwin && !cgo) || (android && amd64) || (darwin && kqueue)
// +build solaris,!cgo darwin,!cgo android,amd64 darwin,kqueue
package fs
+3 -6
View File
@@ -7,6 +7,8 @@
package model
import (
"slices"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/sync"
)
@@ -40,12 +42,7 @@ func (p *deviceFolderDownloadState) Has(file string, version protocol.Vector, in
return false
}
for _, existingIndex := range local.blockIndexes {
if existingIndex == index {
return true
}
}
return false
return slices.Contains(local.blockIndexes, index)
}
// Update updates internal state of what has been downloaded into the temporary
+1 -1
View File
@@ -97,7 +97,7 @@ func (f *fakeConnection) addFileLocked(name string, flags uint32, ftype protocol
file.Name = name
file.Type = ftype
file.Version = version
file.SymlinkTarget = string(data)
file.SymlinkTarget = data
file.NoPermissions = true
}
f.files = append(f.files, file)
+2 -2
View File
@@ -743,7 +743,7 @@ func (f *sendReceiveFolder) handleSymlink(file protocol.FileInfo, snap *db.Snaps
l.Debugf("need symlink\n\t%v\n\t%v", file, curFile)
}
if file.SymlinkTarget == "" {
if len(file.SymlinkTarget) == 0 {
// Index entry from a Syncthing predating the support for including
// the link target in the index entry. We log this as an error.
f.newPullError(file.Name, errIncompatibleSymlink)
@@ -758,7 +758,7 @@ func (f *sendReceiveFolder) handleSymlink(file protocol.FileInfo, snap *db.Snaps
// We declare a function that acts on only the path name, so
// we can pass it to InWritableDir.
createLink := func(path string) error {
if err := f.mtimefs.CreateSymlink(file.SymlinkTarget, path); err != nil {
if err := f.mtimefs.CreateSymlink(string(file.SymlinkTarget), path); err != nil {
return err
}
return f.setPlatformData(&file, path)
+2 -2
View File
@@ -891,7 +891,7 @@ func TestCopyOwner(t *testing.T) {
Name: "foo/bar/sym",
Type: protocol.FileInfoTypeSymlink,
Permissions: 0o644,
SymlinkTarget: "over the rainbow",
SymlinkTarget: []byte("over the rainbow"),
}
f.handleSymlink(symlink, snap, dbUpdateChan, scanChan)
@@ -958,7 +958,7 @@ func TestSRConflictReplaceFileByLink(t *testing.T) {
// Simulate remote creating a symlink with the same name
file.Type = protocol.FileInfoTypeSymlink
file.SymlinkTarget = "bar"
file.SymlinkTarget = []byte("bar")
rem := device1.Short()
file.Version = protocol.Vector{}.Update(rem)
file.ModifiedBy = rem
+5 -5
View File
@@ -7,7 +7,7 @@
package model
import (
"errors"
"fmt"
"os/user"
"strings"
@@ -44,7 +44,7 @@ func lookupUserAndGroup(name string, group bool) (string, string, error) {
return "", err
})
if err != nil {
return "", "", err
return "", "", fmt.Errorf("lookup group %v: %w", name, err)
}
return "", gr, nil
}
@@ -57,7 +57,7 @@ func lookupUserAndGroup(name string, group bool) (string, string, error) {
return "", err
})
if err != nil {
return "", "", err
return "", "", fmt.Errorf("lookup user %v: %w", name, err)
}
return us, "", nil
}
@@ -74,9 +74,9 @@ func lookupWithoutDomain(name string, lookup func(s string) (string, error)) (st
}
parts := strings.Split(name, `\`)
if len(parts) == 2 {
if v, err := lookup(parts[1]); err == nil {
if v, err = lookup(parts[1]); err == nil {
return v, nil
}
}
return "", errors.New("lookup failed")
return "", err
}
+3 -3
View File
@@ -66,7 +66,7 @@ type FileInfo struct {
Version Vector
Sequence int64
Blocks []BlockInfo
SymlinkTarget string
SymlinkTarget []byte
BlocksHash []byte
Encrypted []byte
Platform PlatformData
@@ -187,7 +187,7 @@ type FileInfoWithoutBlocks interface {
GetVersion() *bep.Vector
GetSequence() int64
// GetBlocks() []*bep.BlockInfo // not included
GetSymlinkTarget() string
GetSymlinkTarget() []byte
GetBlocksHash() []byte
GetEncrypted() []byte
GetType() FileInfoType
@@ -469,7 +469,7 @@ func (f FileInfo) isEquivalent(other FileInfo, comp FileInfoComparison) bool {
case FileInfoTypeFile:
return f.Size == other.Size && ModTimeEqual(f.ModTime(), other.ModTime(), comp.ModTimeWindow) && (comp.IgnoreBlocks || f.BlocksEqual(other))
case FileInfoTypeSymlink:
return f.SymlinkTarget == other.SymlinkTarget
return bytes.Equal(f.SymlinkTarget, other.SymlinkTarget)
case FileInfoTypeDirectory:
return true
}
+4 -4
View File
@@ -185,15 +185,15 @@ func TestIsEquivalent(t *testing.T) {
// The symlink target is checked for symlinks
{
a: FileInfo{Type: FileInfoTypeSymlink, SymlinkTarget: "a"},
b: FileInfo{Type: FileInfoTypeSymlink, SymlinkTarget: "b"},
a: FileInfo{Type: FileInfoTypeSymlink, SymlinkTarget: []byte("a")},
b: FileInfo{Type: FileInfoTypeSymlink, SymlinkTarget: []byte("b")},
eq: false,
},
// ... but not for non-symlinks
{
a: FileInfo{Type: FileInfoTypeFile, SymlinkTarget: "a"},
b: FileInfo{Type: FileInfoTypeFile, SymlinkTarget: "b"},
a: FileInfo{Type: FileInfoTypeFile, SymlinkTarget: []byte("a")},
b: FileInfo{Type: FileInfoTypeFile, SymlinkTarget: []byte("b")},
eq: true,
},
}
+11 -3
View File
@@ -243,7 +243,7 @@ const walkFailureEventDesc = "Unexpected error while walking the filesystem duri
func (w *walker) scan(ctx context.Context, toHashChan chan<- protocol.FileInfo, finishedChan chan<- ScanResult) {
hashFiles := w.walkAndHashFiles(ctx, toHashChan, finishedChan)
if len(w.Subs) == 0 {
if err := w.Filesystem.Walk(".", hashFiles); err != nil && !errors.Is(err, fs.SkipDir) {
if err := w.Filesystem.Walk(".", hashFiles); isWarnableError(err) {
w.EventLogger.Log(events.Failure, walkFailureEventDesc)
l.Warnf("Aborted scan due to an unexpected error: %v", err)
}
@@ -253,7 +253,7 @@ func (w *walker) scan(ctx context.Context, toHashChan chan<- protocol.FileInfo,
l.Debugf("%v: Skip walking %v as it is below a symlink", w, sub)
continue
}
if err := w.Filesystem.Walk(sub, hashFiles); err != nil && !errors.Is(err, fs.SkipDir) {
if err := w.Filesystem.Walk(sub, hashFiles); isWarnableError(err) {
w.EventLogger.Log(events.Failure, walkFailureEventDesc)
l.Warnf("Aborted scan of path '%v' due to an unexpected error: %v", sub, err)
}
@@ -262,6 +262,14 @@ func (w *walker) scan(ctx context.Context, toHashChan chan<- protocol.FileInfo,
close(toHashChan)
}
// isWarnableError returns true if err is a kind of error we should warn
// about receiving from the folder walk.
func isWarnableError(err error) bool {
return err != nil &&
!errors.Is(err, fs.SkipDir) && // intentional skip
!errors.Is(err, context.Canceled) // folder restarting
}
func (w *walker) walkAndHashFiles(ctx context.Context, toHashChan chan<- protocol.FileInfo, finishedChan chan<- ScanResult) fs.WalkFunc {
now := time.Now()
ignoredParent := ""
@@ -740,7 +748,7 @@ func CreateFileInfo(fi fs.FileInfo, name string, filesystem fs.Filesystem, scanO
if err != nil {
return protocol.FileInfo{}, err
}
f.SymlinkTarget = target
f.SymlinkTarget = []byte(target)
f.NoPermissions = true // Symlinks don't have permissions of their own
return f, nil
}
+1 -1
View File
@@ -367,7 +367,7 @@ func TestWalkSymlinkUnix(t *testing.T) {
if len(files[0].Blocks) != 0 {
t.Errorf("expected zero blocks for symlink, not %d", len(files[0].Blocks))
}
if files[0].SymlinkTarget != "../testdata" {
if string(files[0].SymlinkTarget) != "../testdata" {
t.Errorf("expected symlink to have target destination, not %q", files[0].SymlinkTarget)
}
}
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "STDISCOSRV" "1" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
stdiscosrv \- Syncthing Discovery Server
.SH SYNOPSIS
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "STRELAYSRV" "1" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
strelaysrv \- Syncthing Relay Server
.SH SYNOPSIS
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-BEP" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-bep \- Block Exchange Protocol v1
.SH INTRODUCTION AND DEFINITIONS
+33 -10
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-CONFIG" "5" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-config \- Syncthing Configuration
.SH SYNOPSIS
@@ -861,6 +861,8 @@ for example:
.EE
.UNINDENT
.UNINDENT
.sp
In the GUI, multiple values are separated by commas.
.UNINDENT
.INDENT 0.0
.TP
@@ -871,7 +873,9 @@ True if synchronization with this devices is (temporarily) suspended.
.TP
.B allowedNetwork
If given, this restricts connections to this device to only this network.
The mechanism is described in detail in a \fI\%separate chapter\fP).
The mechanism is described in detail in a \fI\%separate chapter\fP). To configure multiple networks, you
can either: repeat \fB<allowedNetwork>\fP tags in the configuration file or
enter several networks separated by commas in the GUI.
.UNINDENT
.INDENT 0.0
.TP
@@ -902,6 +906,8 @@ despite the config name looking like kilobits/second.
Contains the ID of the folder that should be ignored. This folder will
always be skipped when advertised from the containing remote device,
i.e. this will be logged, but there will be no dialog shown in the web GUI.
Multiple ignored folders are represented by repeated \fB<ignoredFolder>\fP
tags in the configuration file.
.UNINDENT
.INDENT 0.0
.TP
@@ -1201,7 +1207,10 @@ The \fBoptions\fP element contains all other global configuration options.
.TP
.B listenAddress
The listen address for incoming sync connections. See
\fI\%Listen Addresses\fP for the allowed syntax.
\fI\%Listen Addresses\fP for the allowed syntax. To configure multiple
addresses, you can either: repeat \fB<listenAddress>\fP tags in the
configuration file or enter several addresses separated by commas in the
GUI.
.UNINDENT
.INDENT 0.0
.TP
@@ -1212,7 +1221,10 @@ may be present. The syntax for non\-default entries is that of an HTTP or
HTTPS URL. A number of options may be added as query options to the URL:
\fBinsecure\fP to prevent certificate validation (required for HTTP URLs)
and \fBid=<device ID>\fP to perform certificate pinning. The device ID to
use is printed by the discovery server on startup.
use is printed by the discovery server on startup. To configure multiple
servers, you can either: repeat \fB<globalAnnounceServer>\fP tags in the
configuration file or enter several servers separated by commas in the
GUI.
.UNINDENT
.INDENT 0.0
.TP
@@ -1380,7 +1392,10 @@ The URL from which release information is loaded, for automatic upgrades.
.INDENT 0.0
.TP
.B alwaysLocalNet
Network that should be considered as local given in CIDR notation.
Network that should be considered as local given in CIDR notation. To
configure multiple networks, you can either: repeat \fB<alwaysLocalNet>\fP
tags in the configuration file or enter several networks separated by
commas in the GUI.
.UNINDENT
.INDENT 0.0
.TP
@@ -1399,7 +1414,9 @@ into account files that have at least this many blocks.
.TP
.B unackedNotificationID
ID of a notification to be displayed in the web GUI. Will be removed once
the user acknowledged it (e.g. an transition notice on an upgrade).
the user acknowledged it (e.g. a transition notice on an upgrade). Multiple
IDs are represented by repeated \fB<unackedNotificationID>\fP tags in the
configuration file.
.UNINDENT
.INDENT 0.0
.TP
@@ -1422,6 +1439,10 @@ expanded to
\fBstun.sipgate.net:3478\fP, \fBstun.voip.aebc.com:3478\fP,
\fBstun.voiparound.com:3478\fP, \fBstun.voipbuster.com:3478\fP,
\fBstun.voipstunt.com:3478\fP and \fBstun.xten.com:3478\fP (this is the default).
.sp
To configure multiple servers, you can either: repeat \fB<stunServer>\fP tags
in the configuration file or enter several servers separated by commas in
the GUI.
.UNINDENT
.INDENT 0.0
.TP
@@ -1501,7 +1522,9 @@ troubleshooting step and causes high database churn. The default is now
Feature flags are simple strings that, when added to the configuration, may
unleash unfinished or still\-in\-development features to allow early user
testing. Any supported value will be separately announced with the feature,
so that regular users do not enable it by accident.
so that regular users do not enable it by accident. To configure multiple
flags, you can either: repeat \fB<featureFlag>\fP tags in the configuration
file or enter several flags separated by commas in the GUI.
.UNINDENT
.INDENT 0.0
.TP
@@ -1626,9 +1649,9 @@ line is represented as by a \fB<line>\fP element.
.SS Listen Addresses
.sp
The following address types are accepted in sync protocol listen addresses.
If you want Syncthing to listen on multiple addresses, you can either: add
multiple \fB<listenAddress>\fP tags in the configuration file or enter several
addresses separated by commas in the GUI.
If you want Syncthing to listen on multiple addresses, you can either: repeat
\fB<listenAddress>\fP tags in the configuration file or enter several addresses
separated by commas in the GUI.
.INDENT 0.0
.TP
.B Default listen addresses (\fBdefault\fP)
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-DEVICE-IDS" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-device-ids \- Understanding Device IDs
.sp
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-EVENT-API" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-event-api \- Event API
.SH DESCRIPTION
+5 -3
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-FAQ" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-faq \- Frequently Asked Questions
.INDENT 0.0
@@ -264,8 +264,10 @@ using a GUI wrapper integration, it may keep the logs for you.
When troubleshooting a slow sync, there are a number of things to check.
.sp
First of all, verify that you are not connected via a relay. In the “Remote
Devices” list on the right side of the GUI, double check that you see
“Address: <some address>” and \fInot\fP “Relay: <some address>”.
Devices” list on the right side of the GUI, double check that the Connection
Type does \fInot\fP start with “Relay”.
.sp
Here is an example of a device connected via a relay:
[image]
.sp
If you are connected via a relay, this is because a direct connection could
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-GLOBALDISCO" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-globaldisco \- Global Discovery Protocol v3
.SH ANNOUNCEMENTS
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-LOCALDISCO" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-localdisco \- Local Discovery Protocol v4
.SH MODE OF OPERATION
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-NETWORKING" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-networking \- Firewall Setup
.SH ROUTER SETUP
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-RELAY" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-relay \- Relay Protocol v1
.SH WHAT IS A RELAY?
+59 -42
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-REST-API" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-rest-api \- REST API
.sp
@@ -1289,10 +1289,29 @@ not connected. Otherwise it can be either \fBpaused\fP, \fBnotSharing\fP, or
.SS GET /rest/db/file
.sp
Returns most data available about a given file, including version and
availability. Takes \fBfolder\fP and \fBfile\fP parameters. \fBlocal\fP and
\fBglobal\fP refer to the current file on disk and the globally newest file,
respectively.
Returns most data about a given file, including version and availability.
.SS Request
.sp
The call requires parameters for \fBfolder\fP and \fBfile\fP in the query string:
.INDENT 0.0
.IP \(bu 2
\fBfolder\fP is the folder ID which you can find in the Syncthing Web GUI,
e.g. \fB5camp\-slpa8\fP\&.
.IP \(bu 2
\fBfile\fP is the relative path of the file starting from the folder root to the
file you are interested in. The path and filename must be correctly
URL\-encoded.
.UNINDENT
.SS Example Request
.INDENT 0.0
.INDENT 3.5
.sp
.EX
$ curl \-s \-H X\-API\-KEY:... \(dqhttp://localhost:8384/rest/db/file?folder=YOUR_FOLDER_ID\(dq \-\-url\-query \(dqfile=path/to/file.pdf\(dq
.EE
.UNINDENT
.UNINDENT
.SS Response
.INDENT 0.0
.INDENT 3.5
.sp
@@ -1305,55 +1324,53 @@ respectively.
}
],
\(dqglobal\(dq: { /* a file entry */ },
\(dqlocal\(dq: { /* a file entry */ }
}
.EE
.UNINDENT
.UNINDENT
.sp
A file entry looks like this:
.INDENT 0.0
.INDENT 3.5
.sp
.EX
{
{
\(dqdeleted\(dq: false,
\(dqignored\(dq: false,
\(dqinodeChange\(dq: \(dq1970\-01\-01T01:00:00+01:00\(dq,
\(dqinvalid\(dq: false,
\(dqlocalFlags\(dq: 0,
\(dqmodified\(dq: \(dq2022\-09\-28T08:07:19.979723+02:00\(dq,
\(dqmodifiedBy\(dq: \(dq523ITIE\(dq,
\(dqmustRescan\(dq: false,
\(dqname\(dq: \(dqimg\(dq,
\(dqnoPermissions\(dq: false,
\(dqnumBlocks\(dq: 0,
\(dqpermissions\(dq: \(dq0755\(dq,
\(dqplatform\(dq: { /* platform specific data */ },
\(dqsequence\(dq: 914,
\(dqsize\(dq: 128,
\(dqtype\(dq: \(dqFILE_INFO_TYPE_DIRECTORY\(dq,
\(dqversion\(dq: [
\(dq523ITIE:1664345275\(dq
]
},
\(dqlocal\(dq: { /* a file entry */ },
\(dqmtime\(dq: {
\(dqerr\(dq: null,
\(dqvalue\(dq: {
\(dqreal\(dq: \(dq0001\-01\-01T00:00:00Z\(dq,
\(dqvirtual\(dq: \(dq0001\-01\-01T00:00:00Z\(dq
}
}
}
.EE
.UNINDENT
.UNINDENT
.sp
\fBlocal\fP and \fBglobal\fP refer to the current file on the local device and the
globally newest file, respectively. A file entry looks like this:
.INDENT 0.0
.INDENT 3.5
.sp
.EX
{
\(dqdeleted\(dq: false,
\(dqignored\(dq: false,
\(dqinodeChange\(dq: \(dq1970\-01\-01T01:00:00+01:00\(dq,
\(dqinvalid\(dq: false,
\(dqlocalFlags\(dq: 0,
\(dqmodified\(dq: \(dq2022\-09\-28T08:07:19.979723+02:00\(dq,
\(dqmodifiedBy\(dq: \(dq523ITIE\(dq,
\(dqmustRescan\(dq: false,
\(dqname\(dq: \(dqimg\(dq,
\(dqnoPermissions\(dq: false,
\(dqnumBlocks\(dq: 0,
\(dqpermissions\(dq: \(dq0755\(dq,
\(dqplatform\(dq: { /* platform specific data */ },
\(dqsequence\(dq: 914,
\(dqsize\(dq: 128,
\(dqtype\(dq: \(dqFILE_INFO_TYPE_DIRECTORY\(dq,
\(dqversion\(dq: [
\(dq523ITIE:1664345275\(dq
]
}
.EE
.UNINDENT
.UNINDENT
.sp
Platform specific data may be ownership, extended attributes, etc. and is
divided into entries per operating system / platform. An example platform
entry containing ownership information for Unix systems and an extended
attribute for macOS (“darwin”) looks as follows:
divided into entries per operating system / platform. An example platform entry
containing ownership information for Unix systems and an extended attribute for
macOS (“darwin”) looks as follows:
.INDENT 0.0
.INDENT 3.5
.sp
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-SECURITY" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-security \- Security Principles
.sp
+2 -2
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-STIGNORE" "5" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-stignore \- Prevent files from being synchronized to other nodes
.SH SYNOPSIS
@@ -255,7 +255,7 @@ content, make sure it does not have a \fB/\fP at the end of the pattern.
.UNINDENT
.sp
Added in version 1.19.0: Default patterns can be configured which will take effect when automatically
accepting a folder from a remote device. The GUI suggests same the patterns
accepting a folder from a remote device. The GUI suggests the same patterns
when adding a folder manually. In either case, the \fB\&.stignore\fP file is
created with these defaults if none is present yet.
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING-VERSIONING" "7" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing-versioning \- Keep automatic backups of deleted files by other nodes
.sp
+1 -1
View File
@@ -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" "Jan 06, 2025" "v1.28.1" "Syncthing"
.TH "SYNCTHING" "1" "Mar 13, 2025" "v1.29.3" "Syncthing"
.SH NAME
syncthing \- Syncthing
.SH SYNOPSIS
+1 -1
View File
@@ -101,7 +101,7 @@ message FileInfo {
Vector version = 9;
int64 sequence = 10;
repeated BlockInfo blocks = 16;
string symlink_target = 17;
bytes symlink_target = 17;
bytes blocks_hash = 18;
bytes encrypted = 19;
FileInfoType type = 2;
+1 -1
View File
@@ -15,7 +15,7 @@ message FileInfoTruncated {
bep.Vector version = 9;
int64 sequence = 10;
reserved 16; // blocks
string symlink_target = 17;
bytes symlink_target = 17;
bytes blocks_hash = 18;
bytes encrypted = 19;
bep.FileInfoType type = 2;
+6 -6
View File
@@ -45,11 +45,11 @@ func main() {
}
log.Println(curValidLangs)
resp := req("https://hosted.weblate.org/exports/stats/syncthing/gui/?format=json", token)
var stats []stat
err := json.NewDecoder(resp.Body).Decode(&stats)
if err != nil {
resp := req("https://hosted.weblate.org/api/components/syncthing/gui/statistics/", token)
var statRes struct {
Results []stat
}
if err := json.NewDecoder(resp.Body).Decode(&statRes); err != nil {
log.Fatal(err)
}
resp.Body.Close()
@@ -57,7 +57,7 @@ func main() {
names := make(map[string]string)
var langs []string
for _, stat := range stats {
for _, stat := range statRes.Results {
code := reformatLanguageCode(stat.Code)
pct := 100 * stat.Translated / stat.Total
if _, valid := curValidLangs[code]; pct < 75 || !valid && pct < 95 {