Compare commits

...

18 Commits

Author SHA1 Message Date
Jakob Borg bcfd18ceb1 Revert "lib/model, gui: Allow creating and editing ignores of paused folders (fixes #3608)"
This reverts commit 25b314f5f1.
2017-04-15 09:38:23 +02:00
Jakob Borg ce0456b5ac lib/protocol: Accept invalid files without blocks (fixes #4093) 2017-04-12 11:48:27 +02:00
Jakob Borg f0492c4eb3 gui: Per remote device transfer rates should follow setting (fixes #4082) 2017-04-06 10:42:45 +02:00
Jakob Borg b1edf12257 gui, man: Update docs & translations 2017-04-05 17:10:31 +02:00
Jakob Borg 2579e8f715 build: Use tildes in Debian package versioning
Makes their version sorting closer to the semver we expect.
2017-04-05 16:59:37 +02:00
Jakob Borg a1bcc15458 vendor: Mega update all dependencies
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4080
2017-04-05 14:34:41 +00:00
Jakob Borg 49c1527724 vendor: Update github.com/calmh/du (ref #4079) 2017-04-04 14:53:24 +02:00
Jakob Borg da35820fd5 lib/model: Work around Mac filesystem precision in TestIgnores (ref #3996) 2017-04-03 15:47:23 +02:00
Adam Piggott 79eac61b09 gui: Re-word introducer text (fixes #1819)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3831
2017-04-01 11:06:13 +00:00
Jakob Borg 2ff08e6c84 lib/sync: Make some tests not depend on real clock
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4065
2017-04-01 11:03:11 +00:00
Simon Frei 25b314f5f1 lib/model, gui: Allow creating and editing ignores of paused folders (fixes #3608)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3996
LGTM: calmh, AudriusButkevicius
2017-04-01 09:58:06 +00:00
Jakob Borg c5e0c47989 lib/connections, lib/model, gui: Specify allowed networks per device (fixes #219)
This adds a new config AllowedNetworks per device, which when set should
contain a list of network prefixes (192.168.0.0/126 etc) that are
allowed for the given device. The connection service will not attempt
connections to addresses outside of the given networks and incoming
connections will be rejected as well.

I've added the config to the normal device editor and shown it (when
set) in the device summary on the main screen.

There's a unit test for the IsAllowedNetwork method, I've done some
manual sanity testing on top of that.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4073
2017-04-01 09:52:31 +00:00
Jakob Borg 4253f22680 lib/scanner: Use fs.Filesystem for all operations
One more step on the path of the great refactoring. Touches rwfolder a
little bit since it uses the Lstat from fs as well, but mostly this is
just on the scanner as rwfolder is scheduled for a later refactor.

There are a couple of usages of fs.DefaultFilesystem that will in the
end become a filesystem injected from the top, but that comes later.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4070
LGTM: AudriusButkevicius, imsodin
2017-04-01 09:04:11 +00:00
Jakob Borg bdb56d91b9 lib/model: Honor umask when creating folder directories on Unix (fixes #2519)
Doesn't change the behavior on Windows.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4076
2017-03-31 07:51:23 +00:00
Jakob Borg c3820fbbf2 gui: Allow toggleable units for transfer rate (fixes #234)
Click the transfer rate to toggle between binary-exponent bytes (KiB/s,
MiB/s) and metric based bits (kb/s, Mb/s). The setting is persisted in
browser local storage (best effort).

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4074
2017-03-31 06:32:54 +00:00
Jakob Borg cbdb036b69 gui: Handle slices in advanced config, show devices in advanced config (fixes #2267)
The ng-list directive makes angular handle lists by doing comma
separation in the roundtrip. We could simplify our normal config dialog
this way as well...

Also adds devices that were inexplicably not available in the advanced
config.

This reveals some other uglyness, as the "devices" config of a folder
now shows as "[object Object], [object Object]" - previously it was
invisible. I think that's fine for now.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4071
2017-03-30 14:32:58 +00:00
Jakob Borg b75b4190c8 lib/protocol: Add some consistency checks on incoming index updates (fixes #4053)
With this change we will throw a protocol error on some kinds of
malformed index entries.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4064
2017-03-27 07:21:08 +00:00
Simon Frei 1ad547fb65 gui, script: Translate discovery popover and detect it in translate script
Skip-check: pr-solaris

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4061
2017-03-25 11:56:51 +00:00
1439 changed files with 56512 additions and 798340 deletions
+4
View File
@@ -523,6 +523,10 @@ func buildDeb(target target) {
debver := version
if strings.HasPrefix(debver, "v") {
debver = debver[1:]
// Debian interprets dashes as separator between main version and
// Debian package version, and thus thinks 0.14.26-rc.1 is better
// than just 0.14.26. This rectifies that.
debver = strings.Replace(debver, "-", "~", -1)
}
runPrint("fpm", "-t", "deb", "-s", "dir", "-C", "deb",
"-n", "syncthing", "-v", debver, "-a", debarch,
+7
View File
@@ -221,6 +221,13 @@ identicon {
height: 1em;
}
a.toggler {
color: inherit;
}
a.toggler:hover {
border-bottom: 1px dashed;
text-decoration: none;
}
/**
* Progress bars with centered text
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Допълнителни настройки",
"All Data": "Всички данни",
"Allow Anonymous Usage Reporting?": "Разреши анонимно докладване за употребата на програмата?",
"Allowed Networks": "Разрешени мрежи",
"Alphabetic": "Азбучен ред",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Друга команда се занимава с версиите. Тази команда трябва да премахне файла от синхронизираната папка.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Друга команда се занимава с версиите. Тази команда трябва да премахни файла от синхронизираната папка.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Използван процесор",
"Changelog": "Списък с промени",
"Clean out after": "Изчисти след",
"Click to see discovery failures": "Натиснете, за да видите грешки при откриването",
"Close": "Затвори",
"Command": "Команда",
"Comment, when used at the start of a line": "Коментар, използван в началото на реда",
@@ -41,6 +43,7 @@
"Copied from original": "Копиран от оригинала",
"Copyright © 2014-2016 the following Contributors:": "Всички правата запазени © 2014-2016 Сътрудници:",
"Copyright © 2014-2017 the following Contributors:": "Всички правата запазени © 2014-2017. Сътрудници:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Създаване на шаблони за игнориране, презаписване на съществуващ файл в {{path}}.",
"Danger!": "Опасност!",
"Deleted": "Изтрито",
"Device": "Устройство",
@@ -61,6 +64,7 @@
"Edit Device": "Промяна на устройството",
"Edit Folder": "Промяна на папката",
"Editing": "Променяне",
"Editing {%path%}.": "Промяна на {{path}}.",
"Enable NAT traversal": "Разреши NAT traversal",
"Enable Relaying": "Разреши препращане",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Въведете адреси разделени със запетая (\"tcp://ip:port\", \"tcp://host:port\") или \"dynamic\", за да автоматично откриване на наличните адреси.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Advanced settings",
"All Data": "Totes les dades",
"Allow Anonymous Usage Reporting?": "Permetre l'enviament anònim d'informes d'ús?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabètic",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando extern s'encarrega del control de versions. Ha d'eliminar l'arxiu de la carpeta sincronitzada.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Utilització del CPU",
"Changelog": "Historial de canvis",
"Clean out after": "Netejar després",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Tancar",
"Command": "Comando",
"Comment, when used at the start of a line": "Comentari quan és usat al principi d'una línia",
@@ -41,6 +43,7 @@
"Copied from original": "Copiat de l'original",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Perill!",
"Deleted": "Esborrat",
"Device": "Device",
@@ -61,6 +64,7 @@
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Editing": "Modificant",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Enable NAT traversal",
"Enable Relaying": "Enable Relaying",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introdueix adreces separades per comes (\"tcp://ip:port\", \"tcp://host:port\") o \"dinàmic\" per realitzar descobriments automàtics de l'adreça.",
@@ -18,6 +18,7 @@
"Advanced settings": "Ajustos avançats.",
"All Data": "Totes les dades",
"Allow Anonymous Usage Reporting?": "Permetre informes d'ús anònim?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabètic",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando extern controla el versionat. És necessari eliminar el fitxer de la carpeta sincronitzada.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Utilització de la CPU",
"Changelog": "Registre de canvis",
"Clean out after": "Netejar després de",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Tancar",
"Command": "Comando",
"Comment, when used at the start of a line": "Comentar, quant s'utilitza al principi d'una línia",
@@ -41,6 +43,7 @@
"Copied from original": "Copiat de l'original",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 els següents Col·laboradors:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Perill!",
"Deleted": "Esborrat",
"Device": "Device",
@@ -61,6 +64,7 @@
"Edit Device": "Editar Dispositiu",
"Edit Folder": "Editar Carpeta",
"Editing": "Editant",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Permetre NAT transversal",
"Enable Relaying": "Permetre Transmissions",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introdueix adreces separades per coma (\"tcp://ip:port\", \"tcp://host:port\") o \"dynamic\" per a realitzar el descobriment automàtic de l'adreça.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Pokročilá nastavení",
"All Data": "Všechna data",
"Allow Anonymous Usage Reporting?": "Povolit anonymní hlášení o používání?",
"Allowed Networks": "Povolené sítě",
"Alphabetic": "Abecedně",
"An external command handles the versioning. It has to remove the file from the shared folder.": "O verzování se stará externí příkaz. To on musí smazat soubor ze sdíleného adresáře.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Verzování obstarává externí příkaz. Musí odstranit soubor ze sdíleného adresáře.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Využití CPU",
"Changelog": "Changelog",
"Clean out after": "Vyčistit po",
"Click to see discovery failures": "Kliknutím zobrazíte selhání při oznamování",
"Close": "Zavřít",
"Command": "Příkaz",
"Comment, when used at the start of a line": "Komentář, pokud použito na začátku řádku",
@@ -41,6 +43,7 @@
"Copied from original": "Zkopírováno z originálu",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 následující přispěvatelé:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 následující přispěvatelé:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Vytváření ignorovaných vzorů, přepisování existujícího souboru v {{path}}.",
"Danger!": "Pozor!",
"Deleted": "Smazáno",
"Device": "Zařízení",
@@ -61,6 +64,7 @@
"Edit Device": "Upravit zařízení",
"Edit Folder": "Upravit adresář",
"Editing": "Upravuje se",
"Editing {%path%}.": "Editace {{path}}.",
"Enable NAT traversal": "Povolit NAT přenos",
"Enable Relaying": "Povolit přenašeče",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Zadejte adresy oddělené čárkou (\"tcp://ip:port\", \"tcp://host:port\") nebo \"dynamic\" pro automatické zjišťování adres.",
+6 -2
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Avancerede indstillinger",
"All Data": "Alt data",
"Allow Anonymous Usage Reporting?": "Tillad anonym brugerstatistik?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabetisk",
"An external command handles the versioning. It has to remove the file from the shared folder.": "En ekstern kommando styrer versioneringen. Den skal fjerne filen fra den delte mappe.",
"An external command handles the versioning. It has to remove the file from the synced folder.": " ",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU-forbrug",
"Changelog": "Udgivelsesnoter",
"Clean out after": "Rens efter",
"Click to see discovery failures": "Klik for at se opdagelses fejl ",
"Close": "Luk",
"Command": "Kommando",
"Comment, when used at the start of a line": "Kommentering som bruges i starten af en linje",
@@ -41,6 +43,7 @@
"Copied from original": "Kopieret fra originalen",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 de følgende bidragsydere:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 de følgende bidragsydere:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Fare!",
"Deleted": "Slettet",
"Device": "Enhed",
@@ -52,7 +55,7 @@
"Disconnected": "Ikke tilsluttet",
"Discovered": "Opdaget",
"Discovery": "Opslag",
"Discovery Failures": "Discovery Failures",
"Discovery Failures": "Opdagelses Fejl ",
"Documentation": "Dokumentation",
"Download Rate": "Downloadhastighed",
"Downloaded": "Downloadet",
@@ -61,6 +64,7 @@
"Edit Device": "Rediger enhed",
"Edit Folder": "Rediger mappe",
"Editing": "Redigerer",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Aktiver NAT",
"Enable Relaying": "Aktiver Relaying",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Angiv kommaseparerede adresser (\"tcp://ip:port\", \"tcp://host:port\") eller \"dynamic\" for at benytte automatisk opdagelse af adressen.",
@@ -68,7 +72,7 @@
"Error": "Fejl",
"External File Versioning": "Ekstern fil-versionskontrol",
"Failed Items": "Mislykkede filer",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Fejl i forbindelse med opkobling til IPv6 servere skal forventes hvis der ikke er IPv6 forbindelse. ",
"File Pull Order": "Filhentnings rækkefølge",
"File Versioning": "Filversionering",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Filtilladelses bits ignoreres når der søges efter ændringer. Bruges på FAT filsystemer. ",
+14 -10
View File
@@ -18,8 +18,9 @@
"Advanced settings": "Erweiterte Einstellungen",
"All Data": "Alle Daten",
"Allow Anonymous Usage Reporting?": "Übertragung von anonymen Nutzungsberichten erlauben?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alphabetisch",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Ein externer Befehl führt die Versionierung durch. Dazu muss die Datei aus dem geteilten Ordner entfernt werden.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Ein externer Programmaufruf handhabt die Versionierung. Es muss die Datei aus dem zu synchronisierendem Ordner entfernen.",
"Anonymous Usage Reporting": "Anonymer Nutzungsbericht",
"Any devices configured on an introducer device will be added to this device as well.": "Alle Geräte, die beim Verteiler eingetragen sind, werden auch bei diesem Gerät eingetragen",
@@ -30,6 +31,7 @@
"CPU Utilization": "Prozessorauslastung",
"Changelog": "Änderungsprotokoll",
"Clean out after": "Löschen nach",
"Click to see discovery failures": "Zum Anzeigen von Gerätesuchfehlern klicken",
"Close": "Schließen",
"Command": "Befehl",
"Comment, when used at the start of a line": "Kommentar, wenn am Anfang der Zeile benutzt.",
@@ -41,6 +43,7 @@
"Copied from original": "Vom Original kopiert",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 der folgenden Unterstützer:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 der folgenden Unterstützer:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Achtung!",
"Deleted": "Gelöscht",
"Device": "Gerät",
@@ -52,7 +55,7 @@
"Disconnected": "Getrennt",
"Discovered": "Ermittelt",
"Discovery": "Gerätesuche",
"Discovery Failures": "Discovery Failures",
"Discovery Failures": "Gerätesuchfehler",
"Documentation": "Dokumentation",
"Download Rate": "Download",
"Downloaded": "Heruntergeladen",
@@ -61,6 +64,7 @@
"Edit Device": "Gerät bearbeiten",
"Edit Folder": "Ordner bearbeiten",
"Editing": "Bearbeitet",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "NAT-Durchdringung aktivieren",
"Enable Relaying": "Weiterleitung aktivieren",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Kommagetrennte Adressen (\"tcp://ip:port\", \"tcp://host:port\") oder \"dynamic\" eingeben, um die Adresse automatisch zu ermitteln.",
@@ -68,13 +72,13 @@
"Error": "Fehler",
"External File Versioning": "Externe Dateiversionierung",
"Failed Items": "Fehlgeschlagene Objekte",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Es wird ein Verbindungsfehler zu IPv6-Servern erwartet, wenn es keine IPv6-Konnektivität gibt.",
"File Pull Order": "Dateiübertragungsreihenfolge",
"File Versioning": "Dateiversionierung",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Dateizugriffsrechte beim Suchen nach Veränderungen ignorieren. Bei FAT-Dateisystemen zu verwenden.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Files are moved to .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Dateien werden in das .stversions-Verzeichnis verschoben, wenn sie von Syncthing ersetzt oder gelöscht werden.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Wenn Syncthing Dateien ersetzt oder löscht, werden sie in den Ordner .stversions verschoben.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Dateien werden mit einem Datumsstempel im Namen versehen und in ein .stversions-Verzeichnis verschoben, wenn sie von Syncthing ersetzt oder gelöscht werden.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Dateien werden, bevor Syncthing sie löscht oder ersetzt, datiert in den Ordner .stversions verschoben.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dateien sind auf diesem Gerät schreibgeschützt. Auf diesem Gerät durchgeführte Veränderungen werden aber auf den Rest des Verbunds übertragen.",
"Folder": "Ordner",
@@ -87,7 +91,7 @@
"GUI Authentication Password": "Passwort für Zugang zur Benutzeroberfläche",
"GUI Authentication User": "Nutzername für Zugang zur Benutzeroberfläche",
"GUI Listen Addresses": "Adresse(n) für die Benutzeroberfläche",
"GUI Theme": "GUI Thema",
"GUI Theme": "GUI-Theme",
"Generate": "Generieren",
"Global Changes": "Globale Änderungen",
"Global Discovery": "Globale Gerätesuche",
@@ -142,7 +146,7 @@
"Override Changes": "Änderungen überschreiben",
"Path": "Pfad",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Pfad zum Ordner auf dem lokalen Gerät. Ordner wird erzeugt, wenn er nicht existiert. Das Tilden-Zeichen (~) kann als Abkürzung benutzt werden für",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Pfad, in dem Versionen gespeichert werden sollen (leer lassen, wenn das Standard-.stversions-Verzeichnis im geteilten Ordner verwendet werden soll).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Pfad in dem alte Dateiversionen gespeichert werden sollen (ohne Angabe wird der Ordner .stversions im Ordner verwendet).",
"Pause": "Pause",
"Pause All": "Alles pausieren",
@@ -157,7 +161,7 @@
"Random": "Zufall",
"Reduced by ignore patterns": "Durch Ignoriermuster reduziert",
"Release Notes": "Veröffentlichungsnotizen",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Veröffentlichungskandidaten enthalten die neuesten Funktionen und Verbesserungen. Sie entsprechen den traditionellen zweiwöchentlichen Syncthing-Veröffentlichungen.",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Veröffentlichungskandidaten enthalten die neuesten Funktionen und Verbesserungen. Sie ähneln den traditionellen zweiwöchentlichen Syncthing-Veröffentlichungen.",
"Remote Devices": "Fern-Geräte",
"Remove": "Entfernen",
"Required identifier for the folder. Must be the same on all cluster devices.": "Erforderlicher Bezeichner für den Ordner. Muss auf allen Verbund-Geräten gleich sein.",
@@ -195,8 +199,8 @@
"Smallest First": "Kleinstes zuerst",
"Source Code": "Quellcode",
"Stable releases and release candidates": "Stabile Veröffentlichungen und Veröffentlichungskandidaten",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabile Veröffentlichungen werden ca. 2 Wochen verzögert. Während dieser Zeit durchlaufen sie eine Testphase als Veröffentlichungskandidaten.",
"Stable releases only": "Ausschließlich stabile Releases",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabile Veröffentlichungen werden ca. 2 Wochen zurückgehalten. Während dieser Zeit durchlaufen sie eine Testphase als Veröffentlichungskandidaten.",
"Stable releases only": "Ausschließlich stabile Veröffentlichungen",
"Staggered File Versioning": "Stufenweise Dateiversionierung",
"Start Browser": "Browser starten",
"Statistics": "Statistiken",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Προχωρημένες ρυθμίσεις",
"All Data": "Όλα τα δεδομένα",
"Allow Anonymous Usage Reporting?": "Να επιτρέπεται η αποστολή ανώνυμων στοιχείων χρήσης;",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Αλφαβητικά",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Μια εξωτερική εντολή χειρίζεται την τήρηση εκδόσεων και αναλαμβάνει να αφαιρέσει το αρχείο από τον συγχρονισμένο φάκελο.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Μια εξωτερική εντολή χειρίζεται την διαχείριση εκδόσεων. Χρειάζεται να αφαιρέσει το αρχείο από το φάκελο συγχρονισμένων.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Επιβάρυνση του επεξεργαστή",
"Changelog": "Πληροφορίες εκδόσεων",
"Clean out after": "Εκκαθάριση μετά από",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Τέλος",
"Command": "Εντολή",
"Comment, when used at the start of a line": "Σχόλιο, όταν χρησιμοποιείται στην αρχή μιας γραμμής",
@@ -41,6 +43,7 @@
"Copied from original": "Έχει αντιγραφεί από το πρωτότυπο",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 για τους παρακάτω συνεισφέροντες:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 για τους παρακάτω συνεισφέροντες:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Προσοχή!",
"Deleted": "Διαγραμμένα",
"Device": "Συσκευή",
@@ -61,6 +64,7 @@
"Edit Device": "Επεξεργασία συσκευής",
"Edit Folder": "Επεξεργασία φακέλου",
"Editing": "Επεξεργασία σε εξέλιξη",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Ενεργοποίηση διάσχισης NAT",
"Enable Relaying": "Ενεργοποίηση αναμετάδοσης",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Εισάγετε τις διευθύνσεις χωρισμένες με κόμμα (\"tcp://ip:port\", \"tcp://host:port\") ή γράψτε \"dynamic\" για την αυτόματη ανεύρεση τους.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Advanced settings",
"All Data": "All Data",
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU Utilisation",
"Changelog": "Changelog",
"Clean out after": "Clean out after",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Close",
"Command": "Command",
"Comment, when used at the start of a line": "Comment, when used at the start of a line",
@@ -41,6 +43,7 @@
"Copied from original": "Copied from original",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Danger!",
"Deleted": "Deleted",
"Device": "Device",
@@ -61,6 +64,7 @@
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Editing": "Editing",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Enable NAT traversal",
"Enable Relaying": "Enable Relaying",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.",
+2
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Advanced settings",
"All Data": "All Data",
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU Utilization",
"Changelog": "Changelog",
"Clean out after": "Clean out after",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Close",
"Command": "Command",
"Comment, when used at the start of a line": "Comment, when used at the start of a line",
+143 -139
View File
@@ -1,7 +1,7 @@
{
"A device with that ID is already added.": "Aparato kiu ID jam estis aldonita.",
"A negative number of days doesn't make sense.": "Negativa numero de tagoj ne sencas.",
"A new major version may not be compatible with previous versions.": "Nova ĉefa versio eble ne kongruas kun antaŭaj versioj.",
"A device with that ID is already added.": "Aparato kies ID estis jam aldonita.",
"A negative number of days doesn't make sense.": "Negativa numero de tagoj sen senco.",
"A new major version may not be compatible with previous versions.": "Nova ĉefa versio eble ne kongruanta kun antaŭaj versioj.",
"API Key": "API Ŝlosilo",
"About": "Pri",
"Action": "Ago",
@@ -14,37 +14,40 @@
"Address": "Adreso",
"Addresses": "Adresoj",
"Advanced": "Altnivela",
"Advanced Configuration": "Altinivela Agordo",
"Advanced Configuration": "Altnivela Konfiguro",
"Advanced settings": "Altnivelaj agordoj",
"All Data": "Ĉioj Datumoj",
"Allow Anonymous Usage Reporting?": "Permesi Sennoman Raporton de Uzado?",
"All Data": "Ĉiuj Datumoj",
"Allow Anonymous Usage Reporting?": "Permesi Anoniman Raporton de Uzado?",
"Allowed Networks": "Permesitaj Retoj",
"Alphabetic": "Alfabeta",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Externa komando traktas la versionadon. Ĝi havas forigi la dosiero el la sinkronigita dosierujo.",
"Anonymous Usage Reporting": "Sennoma Raporto de Uzado",
"Any devices configured on an introducer device will be added to this device as well.": "Iu devizo agordita en prezentista aparato ankaŭ estos aldonita al ĉi tiu aparato .",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Aŭtomata ĝisdatigo nun proponas la elekto inter stabilaj eldonoj kaj antaŭeldonoj.",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Ekstera komando manipulas la version. Ĝi devas forigi la dosieron el la partigita dosierujo.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Ekstera komando manipulas la version. Ĝi devas forigi la dosieron el la sinkronigita dosierujo.",
"Anonymous Usage Reporting": "Anonima Raporto de Uzado",
"Any devices configured on an introducer device will be added to this device as well.": "Ajna aparatoj agorditaj sur enkondukanto aparato estos ankaŭ aldonita al ĉi tiu aparato.",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Aŭtomata ĝisdatigo nun proponas la elekton inter stabilaj eldonoj kaj kandidataj eldonoj.",
"Automatic upgrades": "Aŭtomataj ĝisdatigoj",
"Be careful!": "Zorgu!",
"Bugs": "Cimoj",
"CPU Utilization": "Ĉefprocesoro Utiligo",
"Be careful!": "Atentu!",
"Bugs": "Bugoj",
"CPU Utilization": "Ĉefprocesoro Uzo",
"Changelog": "Ŝanĝoprotokolo",
"Clean out after": "Purigi poste",
"Click to see discovery failures": "Klaku por vidi malsukcesajn malkovrojn",
"Close": "Fermi",
"Command": "Komando",
"Comment, when used at the start of a line": "Komento, kiam uzita ĉe la komenco de la lineo",
"Comment, when used at the start of a line": "Komento, kiam uzita ĉe la komenco de lineo",
"Compression": "Densigo",
"Configured": "Agordita",
"Connection Error": "Eraro de Konekto",
"Connection Type": "Tipo de Konekto",
"Copied from elsewhere": "Kopiita de aliloke",
"Copied from original": "kopiita de originala",
"Copyright © 2014-2016 the following Contributors:": "Kopirajto © 2014-2016 el la sekvantaj Kontribuantoj:",
"Copyright © 2014-2017 the following Contributors:": "Kopirajto © 2014-2017 el la sekvantaj Kontribuantoj:",
"Copied from elsewhere": "Kopiita el aliloke",
"Copied from original": "Kopiita el la originalo",
"Copyright © 2014-2016 the following Contributors:": "Kopirajto © 2014-2016 por la sekvantaj Kontribuantoj:",
"Copyright © 2014-2017 the following Contributors:": "Kopirajto © 2014-2017 por la sekvantaj Kontribuantoj:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Kreante ignori skemojn, anstataŭige ekzistantan dosieron ĉe {{path}}.",
"Danger!": "Danĝero!",
"Deleted": "Forigita",
"Device": "Aparato",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Aparato \"{{name}}\" ({{device}} ĉe {{address}}) volas konekti. Aldoni la novan devizon?",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Aparato \"{{name}}\" ({{device}} ĉe {{address}}) volas konekti. Aldoni la novan aparaton?",
"Device ID": "Aparato ID",
"Device Identification": "Identigo de Aparato",
"Device Name": "Nomo de Aparato",
@@ -52,57 +55,58 @@
"Disconnected": "Malkonektita",
"Discovered": "Malkovrita",
"Discovery": "Malkovro",
"Discovery Failures": "Discovery Failures",
"Discovery Failures": "Malkovritaj Fiaskoj",
"Documentation": "Dokumentado",
"Download Rate": "Elŝutrapido",
"Download Rate": "Elŝutado rapida",
"Downloaded": "Elŝutita",
"Downloading": "Elŝutado",
"Edit": "Redakti",
"Edit Device": "Redakti Aparato",
"Edit Folder": "Redakti Dosierujo",
"Edit Device": "Redakti Aparaton",
"Edit Folder": "Redakti Dosierujon",
"Editing": "Redaktado",
"Enable NAT traversal": "Ŝaltu trairadan NAT",
"Enable Relaying": "Ŝaltu Relajsado",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Enigi adresojn dividitajn per komoj (\"tcp://ip:port\", \"tcp://host:port\") aŭ \"dynamic\" por elfari aŭtomatan elkovron de la adreso.",
"Enter ignore patterns, one per line.": "Enigi modelrekonojn por ignori, unu per lineo.",
"Editing {%path%}.": "Redaktado {{path}}.",
"Enable NAT traversal": "Ŝaltu trairan NAT",
"Enable Relaying": "Ŝaltu Relajsadon",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Enigi adresojn dividitajn per komoj (\"tcp://ip:port\", \"tcp://host:port\") aŭ \"dynamic\" por elfari aŭtomatan malkovradon de la adreso.",
"Enter ignore patterns, one per line.": "Entajpu ignori skemojn, unu po linio.",
"Error": "Eraro",
"External File Versioning": "Externa Versionado de Dosiero",
"Failed Items": "Malsuksesaj Elementoj",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"File Pull Order": "Ordo de Tiro de Dosieroj",
"External File Versioning": "Ekstera Versionado de Dosiero",
"Failed Items": "Malsukcesaj Eroj",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Malsukceso por konekti al IPv6 serviloj atendante se ekzistas neniu IPv6 konektebleco.",
"File Pull Order": "Ordo por Tiri Dosieron",
"File Versioning": "Versionado de Dosieroj",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Permesoj bitoj de dosieroj estas ignorita dum la serĉado por ŝanĝoj. Uzi en FAT dosiersistemoj.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Files are moved to .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Dosieroj estas movitaj al .stversions dosierujo kiam anstataŭigitaj aŭ forigitaj je Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Dosieroj estas movitaj al datostampitaj versioj en .stversions dosierujo kiam anstataŭigitaj aŭ forigitaj je 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.": "Dosieroj estas protektata de ŝanĝoj faritaj en aliaj aparatoj, sed ŝanĝoj farita en ĉi tiu aparato estos senditaj al resto de la fasko.",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Permesoj bitaj de dosieroj estas ignorita dum la serĉado por ŝanĝoj. Uzi en FAT dosiersistemoj.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Dosieroj estas movigitaj al .stversiaj dosierujoj kiam anstataŭigitaj aŭ forigitaj en Syncthing.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Dosieroj estas movigitaj al .stversions dosierujo kiam anstataŭigitaj aŭ forigitaj en Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Dosieroj estas movigitaj al date stampitaj versioj en .stversiaj dosierujo kiam ili estas anstataŭigitaj aŭ forigitaj en Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Dosieroj estas movigitaj al datostampitaj versioj en .stversions dosierujoj kiam ili estas anstataŭigitaj aŭ forigitaj en 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.": "Dosieroj estas protektataj kontraŭ ŝanĝoj faritaj en aliaj aparatoj, sed ŝanĝoj faritaj en ĉi tiu aparato estos senditaj al cetera parto de la grupo.",
"Folder": "Dosierujo",
"Folder ID": "Dosierujo ID",
"Folder Label": "Etikedo de Dosierujo",
"Folder Path": "Vojo de Dosierujo",
"Folder Type": "Tipo de Dosierujo",
"Folder ID": "Dosieruja ID",
"Folder Label": "Dosieruja Etikedo",
"Folder Path": "Dosieruja Vojo",
"Folder Type": "Dosieruja Tipo",
"Folders": "Dosierujoj",
"GUI": "Grafika Interfaco",
"GUI Authentication Password": "Perpasvorto de Aŭtentigo en Grafika Interfaco",
"GUI Authentication User": "Uzanto de Aŭtentigo en Grafika Interfaco",
"GUI Listen Addresses": "Adreso de Aŭkultado en Grafika Interfaco",
"GUI Authentication Password": "Pasvorta Aŭtentigo en Grafika Interfaco",
"GUI Authentication User": "Uzanta Aŭtentigo en Grafika Interfaco",
"GUI Listen Addresses": "Aŭskultado de Adresoj en Grafika Interfaco",
"GUI Theme": "Etoso de Grafika Interfaco",
"Generate": "Generi",
"Global Changes": "Mallokaj Ŝanĝoj",
"Global Discovery": "Malloka Malkovro",
"Global Discovery Servers": "Mallokaj Serviojn por Malkovrado",
"Global State": "Malloka Stato",
"Global Changes": "Kompletaj Ŝanĝoj",
"Global Discovery": "Kompleta Malkovro",
"Global Discovery Servers": "Kompleta Malkovrado de Serviloj",
"Global State": "Kompleta Stato",
"Help": "Helpo",
"Home page": "Hejmpaĝo",
"Home page": "Hejma paĝo",
"Ignore": "Ignoru",
"Ignore Patterns": "Modelrekonoj por Ignori",
"Ignore Permissions": "Permesoj por Ignori",
"Incoming Rate Limit (KiB/s)": "Limo de Envenrapido (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Malĝusta agordo povas difekti viajn enhavojn en dosierujo kaj turni Syncthing-n senefika.",
"Introduced By": "Prezentita Per",
"Introducer": "Prezentista",
"Inversion of the given condition (i.e. do not exclude)": "Inversigo de la donita kondiĉo (i.e. ne ekskluzivi)",
"Ignore Patterns": "Ignori Ŝablonojn",
"Ignore Permissions": "Ignori Permesojn",
"Incoming Rate Limit (KiB/s)": "Alvenanta Limo Rapideco (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Erara agordo povas difekti viajn dosierujajn enhavojn kaj senefikigi Syncthing-n.",
"Introduced By": "Enkondukita Per",
"Introducer": "Enkondukita",
"Inversion of the given condition (i.e. do not exclude)": "Inversigo de la donita kondiĉo (i.e. ne ekskludas)",
"Keep Versions": "Konservi Versiojn.",
"Largest First": "Plej Granda Unue",
"Last File Received": "Lasta Dosiero Ricevita",
@@ -113,65 +117,65 @@
"Learn more": "Lerni pli",
"Listeners": "Aŭskultantoj",
"Local Discovery": "Loka Malkovro",
"Local State": "Loca Stato",
"Local State (Total)": "Loca Stato (Totala)",
"Local State": "Loka Stato",
"Local State (Total)": "Loka Stato (Tuta)",
"Major Upgrade": "Ĉefa Ĝisdatigo",
"Master": "Ĉefa",
"Maximum Age": "Maksimuma Aĝo",
"Metadata Only": "Nur Metadatumoj",
"Minimum Free Disk Space": "Minimuma Libera Diskospaco",
"Move to top of queue": "Movi supren en la atendovico",
"Multi level wildcard (matches multiple directory levels)": "Plurpaŝa ĵokero (kongruas kun multoblaj niveloj de dosierujoj)",
"Multi level wildcard (matches multiple directory levels)": "Multi nivelo ĵokero (egalas multoblajn dosierujaj niveloj)",
"Never": "Neniam",
"New Device": "Nova Aparato",
"New Folder": "Dova Dosierujo",
"Newest First": "Plejnova Unue",
"No": "Ne",
"No File Versioning": "Sen Versionado de Dosieroj",
"No upgrades": "Sen ĝidatigoj",
"No File Versioning": "Sen Dosiera Versionado",
"No upgrades": "Sen ĝisdatigoj",
"Normal": "Normala",
"Notice": "Rimarko",
"Notice": "Avizo",
"OK": "Bone",
"Off": "For",
"Oldest First": "Maljuna Unue",
"Optional descriptive label for the folder. Can be different on each device.": "Malnepra priskriba etikedo por la dosierujo. Povas esti malsama en ĉiu aparato.",
"Oldest First": "Malnova Unue",
"Optional descriptive label for the folder. Can be different on each device.": "Laŭvola priskriba etikedo por la dosierujo. Povas esti malsama en ĉiu aparato.",
"Options": "Opcioj",
"Out of Sync": "Elsinkronigita",
"Out of Sync Items": "Elementoj Elsinkronigitaj",
"Outgoing Rate Limit (KiB/s)": "Limo de Elirantrapido (KiB/s)",
"Out of Sync Items": "Elsinkronigitaj Eroj",
"Outgoing Rate Limit (KiB/s)": "Limo de Eliranta Rapideco (KiB/s)",
"Override Changes": "Transpasi Ŝanĝojn",
"Path": "Vojo",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Vojo de la dosierujo en la loka komputilo. Kreiĝos se ne ekzistas. La tildo signo (~) povas esti uzata kiel ŝparvojo por",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Vojo kie vesioj esti konservita (lasi malplena por la defaŭlta .stversions dosierujo en la dosierujo).",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Vojo de la dosierujo en la loka komputilo. Kreiĝos se ne ekzistas. La tilda signo (~) povas esti uzata kiel mallongigilo por",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Vojo kies versioj devus esti stokitaj (lasi malplena por la defaŭlta .stversiaj dosierujoj en la dividita dosierujo).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Vojo kies vesioj estas konservitaj (lasi malplena por la defaŭlta .stversiaj dosierujoj en la dosierujo).",
"Pause": "Paŭzu",
"Pause All": "Paŭzu Ĉion",
"Paused": "Paŭzita",
"Please consult the release notes before performing a major upgrade.": "Bonvolu konsulti la eldonaj notoj antaŭ elfaranta ĉefan ĝisdatigon.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Bonvolu agordi Uzanto kaj Perpasvorto de Aŭtentigo en Grafika Interfaco en la dialogo de Agordoj.",
"Please consult the release notes before performing a major upgrade.": "Bonvolu konsulti la eldonitajn notojn antaŭ elfari ĉefan ĝisdatigon.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Bonvolu agordi GUI Authentication Uzanto kaj Pasvorto en la agordoj dialogo.",
"Please wait": "Bonvolu atendi",
"Preview": "Antaŭrigardo",
"Preview Usage Report": "Antaŭrigardo de Raporto de Uzado",
"Quick guide to supported patterns": "Manlibreto por subtenataj modelrekonoj",
"RAM Utilization": "RAM Utiligo",
"Preview Usage Report": "Antaŭrigardo Uzada Raporto",
"Quick guide to supported patterns": "Rapida gvidisto al subtenata ŝablonoj",
"RAM Utilization": "RAM Utiligado",
"Random": "Hazarda",
"Reduced by ignore patterns": "Reduktita per modelrekonoj por ignori",
"Release Notes": "Eldonaj Notoj",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Antaŭeldonoj enhavas la lastajn funkciojn kaj riparojn. Ili estas similaj al la tradicia dusemajna Syncthing eldonaj.",
"Reduced by ignore patterns": "Reduktita per ignorado de la ŝablonoj",
"Release Notes": "Eldonitaj Notoj",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Kandidataj eldonoj enhavas la lastajn trajtojn kaj korektojn. Ili estas similaj al la tradiciaj dusemajnaj Syncthing ĵetoj.",
"Remote Devices": "Foraj Aparatoj",
"Remove": "Forigu",
"Required identifier for the folder. Must be the same on all cluster devices.": "Nepra identigilo por la dosierujo. Devas esti la sama en ĉiuj aparatoj de la fasko.",
"Required identifier for the folder. Must be the same on all cluster devices.": "Nepra identigilo por la dosierujo. Devas esti la sama en ĉiuj aparatoj de la grupo.",
"Rescan": "Reskanu",
"Rescan All": "Reskanu Ĉion",
"Rescan Interval": "Intervalo de Reskano",
"Restart": "Rekomencu",
"Restart Needed": "Rekomenco Bezonata",
"Restarting": "Rekomencanta",
"Rescan Interval": "Reskana Intervalo",
"Restart": "Restartu",
"Restart Needed": "Restarto Bezonata",
"Restarting": "Restartado",
"Resume": "Daŭrigu",
"Resume All": "Daŭrigu Ĉion",
"Reused": "Reuzata",
"Reused": "Reuzita",
"Save": "Konservu",
"Scan Time Remaining": "Restanta Tempo por Skani",
"Scan Time Remaining": "Skanada Restanta Tempo",
"Scanning": "Skanado",
"Select the devices to share this folder with.": "Elekti la aparatojn por komunigi ĉi tiun dosierujon.",
"Select the folders to share with this device.": "Elekti la dosierujojn por komunigi kun ĉi tiu aparato.",
@@ -180,96 +184,96 @@
"Settings": "Agordoj",
"Share": "Komunigu",
"Share Folder": "Komunigu Dosierujon",
"Share Folders With Device": "Dosierujoj Komunigita Kun Aparato",
"Share Folders With Device": "Dosierujoj Komunigitaj Kun Aparato",
"Share With Devices": "Komunigu Kun Aparatoj",
"Share this folder?": "Komunigi ĉi tion dosierujon?",
"Share this folder?": "Komunigi ĉi tiun dosierujon?",
"Shared With": "Komunigita Kun",
"Show ID": "Montru ID",
"Show QR": "Montru QR",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Montri anstataŭ la Aparato ID en la stato de la fakso. Anoncota al aliaj aparatoj kiel opcia defaŭlta nomo.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Montri anstataŭ la Aparato ID en la stato de la fakso. Aktualigonta al la nomo de la aparato se lasus malplena.",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Montrita anstataŭ ID de Aparato en la statuso de la grupo. Estos anoncita al aliaj aparatoj kiel laŭvola defaŭlta nomo.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Montri anstataŭ ID de Aparato en la statuso de la grupo. Estos ĝisdatigita al la nomo de la aparato sciigante se ĝi estas lasita malplena.",
"Shutdown": "Sistemfermu",
"Shutdown Complete": "Sistemfermon Completigita",
"Shutdown Complete": "Sistemfermu tute",
"Simple File Versioning": "Simpla Versionado de Dosieroj",
"Single level wildcard (matches within a directory only)": "Unuoppaŝa ĵokero (kongruas nur en unu dosierujo)",
"Single level wildcard (matches within a directory only)": "Ununura nivelo ĵokero (egalas nur ene de dosierujo)",
"Smallest First": "Plej Malgranda Unue",
"Source Code": "Fontcodo",
"Stable releases and release candidates": "Stabilaj eldonoj kaj antaŭeldonoj",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabilaj eldonoj prokrastas je ĉirkaŭ du semjanoj. Dum tiu tempo ili iras tra testado kiel aneldonoj.",
"Source Code": "Fontkodo",
"Stable releases and release candidates": "Stabilaj eldonoj kaj kandidataj eldonoj",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabilaj eldonoj prokrastas je ĉirkaŭ du semjanoj. Dum tiu tempo ili estos testataj kiel kandidataj eldonoj.",
"Stable releases only": "Nur stabilaj eldonoj",
"Staggered File Versioning": "Ekŝanceliĝita Versionado de Dosieroj",
"Start Browser": "Lanĉu Retumilon",
"Staggered File Versioning": "Gradigitaj Dosiera versionado",
"Start Browser": "Startu Retumilon",
"Statistics": "Statistikoj",
"Stopped": "Haltiĝita",
"Stopped": "Haltita",
"Support": "Subteno",
"Sync Protocol Listen Addresses": "Adresoj de Aŭskulto de la Protokolo de Elsinkronigo",
"Syncing": "Elsinkronigitado",
"Syncthing has been shut down.": "Syncthing estis elŝaltita.",
"Syncthing includes the following software or portions thereof:": "Syncthing enhavas la sekvantajn programarojn aŭ ĝiajn partojn :",
"Syncthing is restarting.": "Syncthing estas rekomencanta.",
"Syncthing is upgrading.": "Syncthing estas ĝisdatiganta.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing ŝajnas nefunkcii, aŭ ĉi tie estas problemo kun via retkonekto. Reprovanta...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing ŝajnas havi problemon kun la traktado de via peto. Bonvolu aktualigi la paĝon aŭ rekomenci Syncthing se la problemo obstinas.",
"Sync Protocol Listen Addresses": "Sync Protokolo de Aŭskultado de Adresoj",
"Syncing": "Elsinkronado",
"Syncthing has been shut down.": "Syncthing estis malŝaltita.",
"Syncthing includes the following software or portions thereof:": "Syncthing inkluzivas la jenajn programarojn aŭ porciojn ĝiajn:",
"Syncthing is restarting.": "Syncthing estas restartanta.",
"Syncthing is upgrading.": "Syncthing estas ĝisdatigita.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing ŝajnas nefunkcii, aŭ estas problemo kun via retkonekto. Reprovado...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing ŝajnas renkonti problemon kun la traktado de via peto. Bonvolu refreŝigi la paĝon aŭ restarti Syncthing se la problemo daŭras.",
"The Syncthing admin interface is configured to allow remote access without a password.": "La administra interfaco de Syncthing estas agordita por permesi foran atingon sen pasvorto.",
"The aggregated statistics are publicly available at the URL below.": "La sumaj statistikj estas publike disponebla ĉe la URL malsupre.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La agordo estis konservita sed ne aktivigita. Syncthing devas rekomenci por aktivigi la novan agordon.",
"The aggregated statistics are publicly available at the URL below.": "La agregita statistikoj estas publike disponebla ĉe la URL malsupre.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La agordo estis registrita sed ne aktivigita. Syncthing devas restarti por aktivigi la novan agordon.",
"The device ID cannot be blank.": "La aparato ID ne povas esti malplena.",
"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).": "La aparato ID por enigi ĉi tie troviĝas ĉe la dialogo en \"Agoj > Montru ID\" en la alia aparato. Interspacoj kaj streketoj estas opcia (ignorigita).",
"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.": "La ĉifrita raporto de uzado estas sendita ĉiutage. Estas uzita por sekvi komunajn platformojn, dosierujgrandojn kaj aplikaĵversiojn. Se la raporto datumaro ŝanĝas, vi estos avertata per ĉi tiu dialogo denove.",
"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.": "La enigita aparato ID ne ŝajnas valida. Ĝi devas esti signoĉeno de 52 aŭ 56 longo enhavinta leterojn kaj nombrojn, kun interspacoj kaj streketoj opciaj.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "Ka unua komandlinia parametro estas la vojo de la dosierujo kaj la dua parametro estas la relativa vojo en la dosierujo.",
"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).": "La aparato ID por eniri ĉi tie estas trovebla per \"Agoj > Montru ID\" dialogo en la alia aparato. Interspacoj kaj streketoj estas opcio (ignorigita).",
"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.": "La ĉifrita raporto de uzado estas sendata ĉiutage. Ĝi estas uzata por sekvi komunajn platformojn, dosierujajn grandojn kaj aplikaĵajn versiojn. Se la raporto datumaro ŝanĝis, vi estos avertata per ĉi tiu dialogo denove.",
"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.": "La enigita aparato ID ne ŝajnas valida. Ĝi devas esti signoĉeno el 52 aŭ 56 karaktroj longa enhavanta leterojn kaj nombrojn, kun interspacoj kaj streketoj opciaj.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "La unua komandlinia parametro estas la vojo de la dosierujo kaj la dua parametro estas la relativa vojo en la dosierujo.",
"The folder ID cannot be blank.": "La dosierujo ID ne povas esti malplena.",
"The folder ID must be unique.": "La dosierujo ID devas esti unika.",
"The folder path cannot be blank.": "La vojo de la dosierujo ne povas esti malplena.",
"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.": "La sekvantaj intervaloj estas uzinta: dum la unua horo versio estas konservita ĉiu 30 sekundoj, dum la unua tago versio estas konservita ĉiu horo, dum la unua 30 tagoj versio estas konservita ĉiu tago, ĝis la maksimumao versio estas konservita ĉiu semajno.",
"The following items could not be synchronized.": "La sekvantaj elementoj ne povis sinkronigi.",
"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.": "La jenaj intervaloj estas uzataj: dum la unua horo version restas dum ĉiuj 30 sekundoj, dum la unua tago versio restas konservita dum ĉiu horo, dum la unuaj 30 tagoj versio estas konservita dum ĉiu tago, ĝis la maksimumea versio restas konservita dum ĉiu semajno.",
"The following items could not be synchronized.": "La sekvantaj elementoj ne povas esti sinkronigataj.",
"The maximum age must be a number and cannot be blank.": "La maksimuma aĝo devas esti nombro kaj ne povas esti malplena.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "La maksimuma tempo por konservi version (en tagoj, agordi je 0 por konservi versiojn eterne).",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "La minimuma libera procento de diskospaco devas esti poziva numero inter 0 kaj 100 (inkluziva).",
"The number of days must be a number and cannot be blank.": "La nombro de tagoj devas esti nombro kaj ne povas esti malplena.",
"The number of days to keep files in the trash can. Zero means forever.": "La nombro de tagoj por konservi dosieroj en la rubujo. Nulo signifas eterne.",
"The number of old versions to keep, per file.": "La nombro de malnova versioj por konservi, po dosiero.",
"The number of versions must be a number and cannot be blank.": "La nombro de versioj devas esti nombro kaj ne povas esti malplena.",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "La minimuma libera procento de diskospaco devas esti pozitiva nombro inter 0 kaj 100 (inkluziva).",
"The number of days must be a number and cannot be blank.": "La nombro da tagoj devas esti nombro kaj ne povas esti malplena.",
"The number of days to keep files in the trash can. Zero means forever.": "La nombro da tagoj por konservi dosierojn en la rubujo. Nulo signifas eterne.",
"The number of old versions to keep, per file.": "La nombro da malnovaj versioj por konservi, po ĉiu dosiero.",
"The number of versions must be a number and cannot be blank.": "La nombro da versioj devas esti nombro kaj ne povas esti malplena.",
"The path cannot be blank.": "La vojo ne povas esti malplena.",
"The rate limit must be a non-negative number (0: no limit)": "La limo de rapido devas esti pozitiva nombro (0: senlimo)",
"The rescan interval must be a non-negative number of seconds.": "La intervalo de reskano devas esti pozitiva nombro de sekundoj.",
"They are retried automatically and will be synced when the error is resolved.": "Ili estas reprovintaj aŭtomate kaj estos sinkronigitaj kiam la eraro estas solvita.",
"This Device": "Ĉi tio Aparato",
"This can easily give hackers access to read and change any files on your computer.": "Ĉi tio povas facile doni al kodumuloj atingo por legi kaj ŝanĝi ajna dosierojn en via komputilo.",
"This is a major version upgrade.": "Ĉi tio estas ĉefversia plibonigo.",
"The rate limit must be a non-negative number (0: no limit)": "La rapideca limo devas esti pozitiva nombro (0: senlimo)",
"The rescan interval must be a non-negative number of seconds.": "La intervalo de reskano devas esti pozitiva nombro da sekundoj.",
"They are retried automatically and will be synced when the error is resolved.": "Ili estas reprovitaj aŭtomate kaj estos sinkronigitaj kiam la eraro estas solvita.",
"This Device": "Ĉi tiu Aparato",
"This can easily give hackers access to read and change any files on your computer.": "Ĉi tio povas facile doni al kodumuloj atingon por legi kaj ŝanĝi ajnajn dosierojn en via komputilo.",
"This is a major version upgrade.": "Ĉi tio estas ĉefversio ĝisdatigita.",
"Time": "Tempo",
"Trash Can File Versioning": "Versionado de Dosiero en Rubujo",
"Trash Can File Versioning": "Rubujo ebligas Dosieran Versionadon",
"Type": "Tipo",
"Unknown": "Nekonata",
"Unshared": "Nekomunigita",
"Unused": "Neuzita",
"Up to Date": "Ĝisdata",
"Updated": "Ĝisdatigita",
"Upgrade": "Plibonigu",
"Upgrade To {%version%}": "Plibonigi Al {{version}}",
"Upgrading": "Pliboniganta",
"Upload Rate": "Alŝutrapido",
"Upgrade": "Altgradigo",
"Upgrade To {%version%}": "Altgradigi Al {{version}}",
"Upgrading": "Altgradigata",
"Upload Rate": "Alŝutorapideco",
"Uptime": "Daŭro de funkciado",
"Usage reporting is always enabled for candidate releases.": "La raporto de uzado ĉiam estas ŝaltita por antaŭeldonoj.",
"Usage reporting is always enabled for candidate releases.": "Uzada raportado ĉiam ŝaltita por kandidataj ĵetoj.",
"Use HTTPS for GUI": "Uzi HTTPS por grafika interfaco.",
"Version": "Versio",
"Versions Path": "Vojo de Versioj",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versioj estas aŭtomate forigitaj se ili estas pli maljuna ol la maksimuma aĝo aŭ superas la nombro de dosierujoj permesita en intervalo.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Averto, ĉi tiu vojo estas parentdosierujo de ekzistanta dosierujo \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Averto, ĉi tiu vojo estas parentdosierujo de ekzistanta dosierujo \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versioj estas aŭtomate forigita se ili estas pli malnovaj ol la maksimuma aĝo aŭ superas la nombron da dosieroj permesita en intervalo.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Averto, ĉi tiu vojo estas parenta dosierujo de ekzistanta dosierujo \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Averto, ĉi tiu vojo estas parenta dosierujo de ekzistanta dosierujo \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Averto, ĉi tiu vojo estas subdosierujo de ekzistanta dosierujo \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Averto, ĉi tiu vojo estas subdosierujo de ekzistanta dosierujo \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Dum la aldonado de nova aparato, memoru ke ĉi tiu aparato devas esti aldonita en la alia flanko ankaŭ.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Dum la aldonado de nova dosierujo, memoru ke la Dosierujo ID estas uzita por ligi la dosierujojn kune inter aparatoj. Ili estas usklecodistinga kaj devas kongrui ĝuste inter ĉiuj aparatoj.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Dum la aldonado de nova dosierujo, memoru ke la Dosieruja ID estas uzita por ligi la dosierujojn kune inter aparatoj. Ili estas literfakodistingaj kaj devas kongrui precize inter ĉiuj aparatoj.",
"Yes": "Jes",
"You can change your choice at any time in the Settings dialog.": "Vi povas ŝanĝi vian elekton iam en la dialogo de Agordo.",
"You can read more about the two release channels at the link below.": "Vi povas legi pli pri la du eldonkanalo ĉe la malsupra ligilo.",
"You must keep at least one version.": "Vi devas konservi almenŭ unu versio.",
"You can change your choice at any time in the Settings dialog.": "Vi povas ŝanĝi vian elekton iam ajn en la Agorda dialogo.",
"You can read more about the two release channels at the link below.": "Vi povas legi plu pri la du eldonkanaloj per la malsupra ligilo.",
"You must keep at least one version.": "Vi devas konservi almenaŭ unu version.",
"days": "tagoj",
"directories": "dosierujoj",
"files": "dosieroj",
"full documentation": "tuta dokumentado",
"items": "elementoj",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} volas komunigi dosierujo \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} volas komunigi dosierujo \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} volas komunigi dosierujon \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} volas komunigi dosierujon \"{{folderlabel}}\" ({{folder}})."
}
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Ajustes avanzados",
"All Data": "Todos los datos",
"Allow Anonymous Usage Reporting?": "¿Deseas permitir el envío anónimo de informes de uso?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabético",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando externo controla la versión. El fichero debe ser eliminado de la carpeta sincronizada.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Uso de CPU",
"Changelog": "Registro de cambios",
"Clean out after": "Limpiar tras",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Cerrar",
"Command": "Acción",
"Comment, when used at the start of a line": "Comentar, cuando se usa al comienzo de una línea",
@@ -41,6 +43,7 @@
"Copied from original": "Copiado del original",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 los siguientes Colaboradores:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 Los siguientes colaboradores:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "¡Peligro!",
"Deleted": "Eliminado",
"Device": "Dispositivo",
@@ -61,6 +64,7 @@
"Edit Device": "Editar Dispositivo",
"Edit Folder": "Editar Carpeta",
"Editing": "Editando",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Permitir NAT transversal",
"Enable Relaying": "Habilitar Retransmisión",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduzca las direcciones, separadas por comas (\"tcp://ip:port\", \"tcp://host:port\"), o \"dynamic\" para llevar a cabo el descubrimiento automático de la dirección.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Optiones avanzadas",
"All Data": "Todos los datos",
"Allow Anonymous Usage Reporting?": "Permitir reporte anónimo de uso?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabético",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando exterior maneja el control de versiones. Éste tiene que eliminar el archivo de la carpeta sincronizada.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Uso de CPU",
"Changelog": "Registro de cambios",
"Clean out after": "Limpiar después",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Cerrar",
"Command": "Comando",
"Comment, when used at the start of a line": "Comentario, cuando es utilizado al inicio de una línea.",
@@ -41,6 +43,7 @@
"Copied from original": "Copiado del original",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 los siguientes contribuidores:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 los siguientes contribuidores:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Peligro!",
"Deleted": "Suprimido",
"Device": "Dispositivo",
@@ -61,6 +64,7 @@
"Edit Device": "Cambiando dispositivo",
"Edit Folder": "Cambiando repositorio",
"Editing": "Editando",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Habilitar NAT trasversal",
"Enable Relaying": "Habilitar Retransmisión",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduce las direcciones (\"tcp://ip:puerto\", \"tcp://huésped:puerto\") separadas por comas, o \"dynamic\" para ejecutar un descubrimiento automático de la dirección. ",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Parametro aitzinatuak",
"All Data": "Datu guziak",
"Allow Anonymous Usage Reporting?": "Izenik gabeko erabiltze erreportak baimendu?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabetikoa",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Kanpoko kontrolagailu batek fitxeroen bertsioak erabiltzen ditu. Fitxeroak errepertorio sinkronizatutik desagertaraztea berari doakio.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Prozesadorearen erabiltzea",
"Changelog": "Bertsioen historia",
"Clean out after": "Garbi …. epearen ondotik",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Hetsi",
"Command": "Kontrolagailua",
"Comment, when used at the start of a line": "Komentarioa, lerro baten hastean delarik",
@@ -41,6 +43,7 @@
"Copied from original": "Jatorrizkotik kopiatua",
"Copyright © 2014-2016 the following Contributors:": "Copyright 2014-2016, ekarle hauk:",
"Copyright © 2014-2017 the following Contributors:": "Copyright 2014-2017, ekarle hauk:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Lanjera !",
"Deleted": "Kendua",
"Device": "Tresna",
@@ -61,6 +64,7 @@
"Edit Device": "Aldaketa tresna",
"Edit Folder": "Aldaketa partekatze",
"Editing": "Aldaketa",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Ahalbidetu NAT",
"Enable Relaying": "Ahalbidetu lekua hartu",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": " (\"tcp://ip:port\", \"tcp://nom:port\") zuzenbideak sar, krakotx batez separatuak edo bestenaz \"dynamic\", zuzenbidearen xekatze automatikoa aktibatzeko\nTu peux traduire nom et port mot à mot dans la parenthèse, c'est pas des variables du programme, juste du texte explicatif",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Kehittyneet asetukset",
"All Data": "Kaikki data",
"Allow Anonymous Usage Reporting?": "Salli anonyymi käyttöraportointi?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Aakkosellinen",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Ulkoinen komento hallitsee versionnin. Sen täytyy poistaa tiedosto synkronoidusta kansiosta.",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU:n käyttö",
"Changelog": "Muutoshistoria",
"Clean out after": "Puhdista seuraavan ajan kuluttua",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Sulje",
"Command": "Komento",
"Comment, when used at the start of a line": "Kommentti, käytettäessä rivin alussa",
@@ -41,6 +43,7 @@
"Copied from original": "Kopioitu alkuperäisestä lähteestä",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 seuraavat avustajat",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Vaara!",
"Deleted": "Poistettu",
"Device": "Laite",
@@ -61,6 +64,7 @@
"Edit Device": "Muokkaa laitetta",
"Edit Folder": "Muokkaa kansiota",
"Editing": "Muokkaus",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Aktivoi osoitteenmuunnoksen kierto",
"Enable Relaying": "Aktivoi yhteyden välitys",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Syötä osoitteet pilkuilla erotettuina (\"tcp://ip:portti, tcp://nimi:portti\") tai \"dynamic\" käyttääksesi osoitteen automaattista selvitystä.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Paramètres avancés",
"All Data": "Toutes les données",
"Allow Anonymous Usage Reporting?": "Autoriser l'envoi de statistiques d'utilisation anonymisées ?",
"Allowed Networks": "Réseaux autorisés",
"Alphabetic": "Alphabétique",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Une commande externe gère les versions de fichiers. Il lui incombe de supprimer les fichiers dans le répertoire synchronisé.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Une commande externe gère les versions de fichiers. Il lui incombe de supprimer les fichiers dans le répertoire synchronisé.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Utilisation du CPU",
"Changelog": "Historique des versions",
"Clean out after": "Purger après :",
"Click to see discovery failures": "Voir les échecs de découverte",
"Close": "Fermer",
"Command": "Commande",
"Comment, when used at the start of a line": "Commentaire lorsque utilisé en début de ligne",
@@ -41,6 +43,7 @@
"Copied from original": "Copié depuis l'original",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016, les contributeurs suivants:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017, les contributeurs suivants :",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Création de masques d'exclusion, remplacement du fichier existant dans {{path}}.",
"Danger!": "Attention !",
"Deleted": "Supprimé",
"Device": "Appareil",
@@ -61,6 +64,7 @@
"Edit Device": "Modifier l'appareil",
"Edit Folder": "Modifier le partage",
"Editing": "Modifications",
"Editing {%path%}.": "Modification de {{path}}.",
"Enable NAT traversal": "Activer transfert d'adresses NAT",
"Enable Relaying": "Activer le relayage",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Entrer les adresses (\"tcp://ip:port\" ou \"tcp://hôte:port\") séparées par une virgule, ou \"dynamic\" afin d'activer la recherche automatique de l'adresse.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Paramètres avancés",
"All Data": "Toutes les données",
"Allow Anonymous Usage Reporting?": "Autoriser l'envoi de statistiques d'utilisation anonymisées ?",
"Allowed Networks": "Réseaux autorisés",
"Alphabetic": "Alphabétique",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Une commande externe gère les versions de fichiers. Il lui incombe de supprimer les fichiers dans le répertoire synchronisé.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Une commande externe gère les versions de fichiers. Il lui incombe de supprimer les fichiers dans le répertoire synchronisé.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Utilisation du CPU",
"Changelog": "Historique des versions",
"Clean out after": "Purger après :",
"Click to see discovery failures": "Voir les échecs de découverte",
"Close": "Fermer",
"Command": "Commande",
"Comment, when used at the start of a line": "Commentaire lorsque utilisé en début de ligne",
@@ -41,6 +43,7 @@
"Copied from original": "Copié depuis l'original",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016, les contributeurs suivants:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017, les contributeurs suivants :",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Création de masques d'exclusion, remplacement du fichier existant dans {{path}}.",
"Danger!": "Attention !",
"Deleted": "Supprimé",
"Device": "Appareil",
@@ -61,6 +64,7 @@
"Edit Device": "Modifier l'appareil",
"Edit Folder": "Modifier le partage",
"Editing": "Modifications",
"Editing {%path%}.": "Modification de {{path}}.",
"Enable NAT traversal": "Activer la translation d'adresses (NAT)",
"Enable Relaying": "Relayage possible",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Entrer les adresses (\"tcp://ip:port\" ou \"tcp://hôte:port\") séparées par une virgule, ou \"dynamic\" afin d'activer la recherche automatique de l'adresse.",
+6 -2
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Avansearre ynstellings",
"All Data": "Alle data",
"Allow Anonymous Usage Reporting?": "Anonime brûkensrapportaazje tastean?",
"Allowed Networks": "Tasteane Netwurken",
"Alphabetic": "Alfabetysk",
"An external command handles the versioning. It has to remove the file from the shared folder.": "In ekstern kommando soarget foar it ferzjebehear. It moat de triem út de dielde map fuortsmite.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "In ekstern kommando soarget foar it ferzjebehear. It moat de triem út de syngronisearre map fuortsmite.",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU-brûken",
"Changelog": "Feroaringslochboek",
"Clean out after": "Opromje nei",
"Click to see discovery failures": "Klik om ûntdekkingsflaters te besjen",
"Close": "Slute",
"Command": "Kommando",
"Comment, when used at the start of a line": "Kommentaar, wannear as brûkt by it begjin fan in rige",
@@ -41,6 +43,7 @@
"Copied from original": "Oernommen fan orizjineel",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 de folgende bydragers:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 de folgende Bydragers:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Meitsje negear-patroanen dy in besteande triem oerskriuwe yn {{path}}.",
"Danger!": "Gefaar!",
"Deleted": "Fuortsmiten",
"Device": "Apparaat",
@@ -52,7 +55,7 @@
"Disconnected": "Ferbining ferbrutsen",
"Discovered": "Untdekt",
"Discovery": "Untdekking",
"Discovery Failures": "Discovery Failures",
"Discovery Failures": "Untdekkingsflaters",
"Documentation": "Dokumintaasje",
"Download Rate": "Ynlaadfluggens",
"Downloaded": "Ynladen",
@@ -61,6 +64,7 @@
"Edit Device": "Apparaat Bewurkje",
"Edit Folder": "Map Bewurkje",
"Editing": "Bewurkjen",
"Editing {%path%}.": "{{path}} wurd bewurke.",
"Enable NAT traversal": "NAT-trochkruse ynskeakelje",
"Enable Relaying": "Trochjaan tastean",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Fier troch komma's skieden (\"tcp://ip:port\", \"tcp://host:port\") adressen yn of \"dynamic\" om automatyske ûntdekking fan it adres út te fieren.",
@@ -68,7 +72,7 @@
"Error": "Flater",
"External File Versioning": "Ekstern ferzjebehear foar triemen",
"Failed Items": "Mislearre items",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Konneksje mei IPv6-tsjinners wol lykwols net slagje sûnder IPv6-ferbining is.",
"File Pull Order": "Triemlûkfolchoarder",
"File Versioning": "Triemferzjebehear",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Bits foar triemrjochten wurde negearre yn it sykjen foar feroarings. Brûk dit op FAT-triemsystemen.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Haladó beállítások",
"All Data": "Minden adat",
"Allow Anonymous Usage Reporting?": "A névtelen felhasználási adatok elküldhetők?",
"Allowed Networks": "Engedélyezett hálózatok",
"Alphabetic": "ABC sorrendben",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Külső program kezeli a fájlverzió-követést. Az távolítja el a fájlt a megosztott mappából.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Külső program kezeli a fájlverzió-követést. Az távolítja el a fájlt a szinkronizált mappából.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Processzorhasználat",
"Changelog": "Változások",
"Clean out after": "Takarítás",
"Click to see discovery failures": "Kattints ide a feltérképezési hibák megtekintéséhez",
"Close": "Bezárás",
"Command": "Parancs",
"Comment, when used at the start of a line": "Megjegyzés, a sor elején használva",
@@ -41,6 +43,7 @@
"Copied from original": "Eredetiről másolva",
"Copyright © 2014-2016 the following Contributors:": "Szerzői jog © 2014-2016 az alábbi közreműködők:",
"Copyright © 2014-2017 the following Contributors:": "Szerzői jog © 2014-2017 az alábbi közreműködők:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Figyelmen kívül hagyás minták létrehozása, egy létező fájl felülírása itt: {{path}}.",
"Danger!": "Veszély!",
"Deleted": "Törölve",
"Device": "Eszköz",
@@ -61,6 +64,7 @@
"Edit Device": "Eszköz szerkesztése",
"Edit Folder": "Mappa szerkesztése",
"Editing": "Szerkesztés",
"Editing {%path%}.": "{{path}} szerkesztése.",
"Enable NAT traversal": "NAT bejárás engedélyezése",
"Enable Relaying": "Közvetítés engedélyezése",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Vesszővel elválasztva több cím is bevihető (\"tcp://ip:port\", \"tcp://host:port\"), az automatikus felderítéshez a 'dynamic' kulcsszó használatos. ",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Advanced settings",
"All Data": "Semua Data",
"Allow Anonymous Usage Reporting?": "Aktifkan Laporan Penggunaan Anonim?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabet",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Perintah eksternal mengatur pemversian. Dia harus menghapus berkas dari folder yang tersinkronisasi.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Penggunaan CPU",
"Changelog": "Log perubahan",
"Clean out after": "Bersihkan setelah",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Tutup",
"Command": "Perintah",
"Comment, when used at the start of a line": "Komentar, digunakan saat awal baris",
@@ -41,6 +43,7 @@
"Copied from original": "Tersalin dari asal",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Bahaya!",
"Deleted": "Terhapus",
"Device": "Device",
@@ -61,6 +64,7 @@
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Editing": "Menyunting",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Enable NAT traversal",
"Enable Relaying": "Aktifkan Relay",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Masukkan alamat, pisahkan dengan koma (\"tcp://ip:port\", \"tcp://host:port\") atau \"dynamic\" untuk menjalankan penemuan otomatis alamat tersebut.",
+5 -1
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Impostazioni avanzate",
"All Data": "Tutti i Dati",
"Allow Anonymous Usage Reporting?": "Abilitare Statistiche Anonime di Utilizzo?",
"Allowed Networks": "Reti Consentite.",
"Alphabetic": "Alfabetico",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Il controllo versione è gestito da un comando esterno. Quest'ultimo deve rimuovere il file dalla cartella condivisa.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Il controllo versione è gestito da un comando esterno. Quest'ultimo deve rimuovere il file dalla cartella sincronizzata.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Utilizzo CPU",
"Changelog": "Changelog",
"Clean out after": "Svuota dopo",
"Click to see discovery failures": "Clicca per vedere gli errori di rilevamento",
"Close": "Chiudi",
"Command": "Comando",
"Comment, when used at the start of a line": "Per commentare, va inserito all'inizio di una riga",
@@ -41,6 +43,7 @@
"Copied from original": "Copiato dall'originale",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 i seguenti Collaboratori:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 i seguenti Collaboratori:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Pericolo!",
"Deleted": "Cancellato",
"Device": "Dispositivo",
@@ -61,6 +64,7 @@
"Edit Device": "Modifica Dispositivo",
"Edit Folder": "Modifica Cartella",
"Editing": "Modifica di",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Abilita NAT traversal",
"Enable Relaying": "Abilita Reindirizzamento",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Inserisci indirizzi separati da virgola (\"tcp://ip:porta\", \"tcp://host:porta\") oppure \"dynamic\" per effettuare il rilevamento automatico dell'indirizzo.",
@@ -195,7 +199,7 @@
"Smallest First": "Prima il più piccolo",
"Source Code": "Codice Sorgente",
"Stable releases and release candidates": "Rilasci stabili e candidati di rilascio",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Rilasci stabili sono due settimane in ritardo. Durante questo tempo verranno testati come candidati di rilascio.",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Rilasci stabili sono in ritardo di circa due settimane. Durante questo tempo verranno testati come candidati di rilascio.",
"Stable releases only": "Solo rilasci stabili",
"Staggered File Versioning": "Controllo Versione Cadenzato",
"Start Browser": "Avvia Browser",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "高度な設定",
"All Data": "全てのデータ",
"Allow Anonymous Usage Reporting?": "匿名で利用状況をレポートすることを許可しますか?",
"Allowed Networks": "許可されているネットワーク",
"Alphabetic": "アルファベット順",
"An external command handles the versioning. It has to remove the file from the shared folder.": "外部コマンドにバージョン管理を任せます。ここで指定するコマンドは、共有フォルダーからファイルを削除するものでなくてはなりません。",
"An external command handles the versioning. It has to remove the file from the synced folder.": "外部コマンドにバージョンを管理させます。ここで指定するコマンドは、同期フォルダーからファイルを削除するものでなくてはなりません。",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU使用率",
"Changelog": "更新履歴",
"Clean out after": "以下の期間後に完全に削除する",
"Click to see discovery failures": "接続に失敗した探索サーバーを確認するにはクリックしてください",
"Close": "閉じる",
"Command": "コマンド",
"Comment, when used at the start of a line": "行頭で使用された場合、コメント行",
@@ -41,6 +43,7 @@
"Copied from original": "元ファイルからコピー済",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "無視パターンを作成中。既存のファイルが {{path}} にある場合は上書きされます。",
"Danger!": "危険",
"Deleted": "削除",
"Device": "デバイス",
@@ -61,6 +64,7 @@
"Edit Device": "デバイスの編集",
"Edit Folder": "フォルダーの編集",
"Editing": "編集中",
"Editing {%path%}.": "{{path}} を編集中。",
"Enable NAT traversal": "NATトラバーサルを有効にする",
"Enable Relaying": "中継サーバー経由の通信を有効にする",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "アドレスを指定する場合は「tcp://IPアドレス:ポート」または「tcp://ホスト名:ポート」をコンマで区切って入力してください。自動探索を行う場合は「dynamic」と入力してください。",
+6 -2
View File
@@ -18,6 +18,7 @@
"Advanced settings": "고급 설정",
"All Data": "전체 데이터",
"Allow Anonymous Usage Reporting?": "익명 사용 보고서를 보내시겠습니까?",
"Allowed Networks": "허가된 네트워크",
"Alphabetic": "알파벳순",
"An external command handles the versioning. It has to remove the file from the shared folder.": "외부 커맨드가 파일 버전을 관리합니다. 공유된 폴더에서 파일을 삭제해야 합니다.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "외부 커맨드가 파일 버전을 관리합니다. 동기화된 폴더에서 파일을 삭제해야 합니다.",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU 사용률",
"Changelog": "바뀐 점",
"Clean out after": "삭제 후",
"Click to see discovery failures": "탐색 실패 보기",
"Close": "닫기",
"Command": "커맨드",
"Comment, when used at the start of a line": "명령행에서 시작을 할수 있어요.",
@@ -41,6 +43,7 @@
"Copied from original": "원본에서 복사됨",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "무시 패턴 만들기, {{path}}에 존재하는 파일을 덮어쓰기 합니다",
"Danger!": "경고!",
"Deleted": "삭제됨",
"Device": "기기",
@@ -52,7 +55,7 @@
"Disconnected": "연결 끊김",
"Discovered": "탐색됨",
"Discovery": "탐색",
"Discovery Failures": "Discovery Failures",
"Discovery Failures": "탐색 실패",
"Documentation": "문서",
"Download Rate": "다운로드 속도",
"Downloaded": "다운로드됨",
@@ -61,6 +64,7 @@
"Edit Device": "기기 편집",
"Edit Folder": "폴더 편집",
"Editing": "편집",
"Editing {%path%}.": "{{path}} 수정하기.",
"Enable NAT traversal": "NAT traversal 활성화",
"Enable Relaying": "Relaying 활성화",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "주소 자동 검색을 하기 위해서는 \"ip:port\" 형식의 주소들을 쉼표로 구분해서 입력하거나 \"dynamic\"을 입력하세요.",
@@ -68,7 +72,7 @@
"Error": "오류",
"External File Versioning": "외부 파일 버전 관리",
"Failed Items": "실패한 항목",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "IPv6 네트워크에 연결되지 않은 경우 IPv6 서버에 연결 할 수 없습니다.",
"File Pull Order": "파일 동기화 순서",
"File Versioning": "파일 버전 관리",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "파일을 동기화할 때 파일 권한이 무시됩니다. FAT 파일 시스템에서 사용하세요.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Išplėstiniai nustatymai",
"All Data": "Visiems duomenims",
"Allow Anonymous Usage Reporting?": "Siųsti anoniminę naudojimo ataskaitą?",
"Allowed Networks": "Leidžiami tinklai",
"Alphabetic": "Abėcėlės tvarka",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Išorinė komanda apdoroja versijų valdymą. Ji turi pašalinti failą iš bendrinamo aplanko.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Išorinė komanda apdoroja versijų valdymą. Ji turi pašalinti failą iš sinchronizuoto aplanko.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Procesoriaus panaudojimas",
"Changelog": "Pasikeitimai",
"Clean out after": "Išvalyti po",
"Click to see discovery failures": "Spustelėkite, norėdami pamatyti matomumo nesėkmes",
"Close": "Užverti",
"Command": "Komanda",
"Comment, when used at the start of a line": "Komentaras naudojamas naujoje eilutėje",
@@ -41,6 +43,7 @@
"Copied from original": "Nukopijuota iš originalo",
"Copyright © 2014-2016 the following Contributors:": "Autorių teisės © 2014-2016 šių bendraautorių:",
"Copyright © 2014-2017 the following Contributors:": "Autorių teisės © 2014-2017 šių bendraautorių:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Kuriami nepaisomi šablonai, perrašomas esamas failas, esantis {{path}}.",
"Danger!": "Pavojus!",
"Deleted": "Ištrinta",
"Device": "Įrenginys",
@@ -61,6 +64,7 @@
"Edit Device": "Redaguoti įrenginį",
"Edit Folder": "Redaguoti aplanką",
"Editing": "Redagavimas",
"Editing {%path%}.": "Redaguojama {{path}}.",
"Enable NAT traversal": "Leisti kirsti NAT",
"Enable Relaying": "Įjungti retransliavimą",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Įveskite kableliais atskirtus (\"tcp://ip:prievadas\", \"tcp://serveris:prievadas\") adresus arba \"dynamic\", kad atliktumėte automatinį adresų aptikimą.",
+57 -53
View File
@@ -18,11 +18,12 @@
"Advanced settings": "Avanserte innstillinger ",
"All Data": "Alle data",
"Allow Anonymous Usage Reporting?": "Tillat anonym innsamling av brukerdata?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabetisk",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "En ekstern kommando håndterer versjonkontrollen. Den må fjerne filen fra den synkroniserte katalogen.",
"An external command handles the versioning. It has to remove the file from the shared folder.": "En ekstern kommando håndterer versjonkontrollen. Den må fjerne filen fra den delte mappa.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "En ekstern kommando håndterer versjonkontrollen. Den må fjerne filen fra den synkroniserte mappa.",
"Anonymous Usage Reporting": "Anonym innsamling av brukerdata",
"Any devices configured on an introducer device will be added to this device as well.": "Enheter konfigurert på en introduksjonsenhet vil også bli lagt til denne enheten.",
"Any devices configured on an introducer device will be added to this device as well.": "Enheter satt opp på en introduksjonsenhet vil også bli lagt til denne enheten.",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatisk oppgradering lar deg nå få valget mellom ferdige utgaver og utgivelseskandidater.",
"Automatic upgrades": "Automatiske oppdateringer",
"Be careful!": "Vær forsiktig!",
@@ -30,64 +31,67 @@
"CPU Utilization": "CPU-utnyttelse",
"Changelog": "Endringslogg",
"Clean out after": "Tøm etter",
"Click to see discovery failures": "Klikk for å se oppslagsfeil",
"Close": "Lukk",
"Command": "Kommando",
"Comment, when used at the start of a line": "Kommentar, når det blir brukt i starten av en linje.",
"Compression": "Komprimering",
"Configured": "Konfigurert",
"Configured": "Oppsatt",
"Connection Error": "Tilkoblingsfeil",
"Connection Type": "Tilkoblingstype",
"Copied from elsewhere": "Kopiert fra et annet sted",
"Copied from original": "Kopiert fra original",
"Copyright © 2014-2016 the following Contributors:": "Opphavsrett © 2014-2016 for følgende bidragsytere:",
"Copyright © 2014-2017 the following Contributors:": "Opphavsrett © 2014-2017 for følgende bidragsytere:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Fare!",
"Deleted": "Slettet",
"Device": "Enhet",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Enhet \"{{name}}\" ({{device}} på {{address}}) ønsker å koble til. Legge til ny enhet?",
"Device ID": "Enhets ID",
"Device ID": "Enhets-ID",
"Device Identification": "Enhetskjennemerke",
"Device Name": "Navn på enhet",
"Devices": "Enheter",
"Disconnected": "Frakoblet",
"Discovered": "Oppdaget",
"Discovery": "Oppslag",
"Discovery Failures": "Discovery Failures",
"Discovery Failures": "Oppslagsfeil",
"Documentation": "Dokumentasjon",
"Download Rate": "Nedlastingsrate",
"Downloaded": "Lastet ned",
"Downloading": "Laster ned",
"Edit": "Rediger",
"Edit Device": "Rediger enhet",
"Edit Folder": "Rediger katalog",
"Edit Folder": "Rediger mappe",
"Editing": "Redigerer",
"Enable NAT traversal": "Slå på NAT traversering",
"Enable Relaying": "Aktiver relésending",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Skriv inn kommaseparerte (\"tcp://ip:port\", \"tcp://host:port\") adresser, eller ordet \"dynamic\" for å gjøre automatisk oppslag for adressen.",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Slå på NAT-traversering",
"Enable Relaying": "Aktiver reléforsendelse",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Skriv inn kommaseparerte (\"tcp://ip:port\", \"tcp://host:port\") adresser, eller ordet \"dynamic\" for å gjøre automatisk oppslag i adressen.",
"Enter ignore patterns, one per line.": "Skriv inn mønster som skal utelates, ett per linje.",
"Error": "Feilmelding",
"External File Versioning": "Ekstern versjonskontroll",
"Failed Items": "Elementsynkronisering som har feilet",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"File Pull Order": "Filenes Henterekkefølge",
"Failed Items": "Elementsynkronisering som har mislyktes",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Å ikke klare å koble til IPv6-tjenere er forventet hvis det ikke er noen IPv6-tilknytning.",
"File Pull Order": "Filenes henterekkefølge",
"File Versioning": "Versjonskontroll",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Informasjon om filrettigheter ignoreres når det letes etter endringer. Bruk på FAT filsystem. ",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Files are moved to .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Filer som slettes eller erstattes av Syncthing flyttes til katalogen .stversions.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Filer flyttes til en datostemplet versjon i .stversions-katalogen når den oppdateres eller slettes av Syncthing.",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Informasjon om filrettigheter ignoreres når det letes etter endringer. Bruk på FAT-filsystemer.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Filer som slettes eller erstattes av Syncthing flyttes til mappa .stversions.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Filer som slettes eller erstattes av Syncthing flyttes til mappa .stversions.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Filer flyttes til en datostemplet versjon i .stversions-mappa når den oppdateres eller slettes av Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Filer flyttes til en datostemplet versjon i .stversions-mappa når den oppdateres eller slettes av 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.": "Filer er beskyttet mot endringer som er gjort på andre enheter, men endringer som er gjort på denne enheten blir sendt til resten av gruppen.",
"Folder": "Katalog",
"Folder ID": "Mappe ID",
"Folder Label": "Merkelapp for katalog",
"Folder": "Mappe",
"Folder ID": "Mappe-ID",
"Folder Label": "Merkelapp for mappe",
"Folder Path": "Mappeplassering",
"Folder Type": "Katalogtype",
"Folder Type": "Mappetype",
"Folders": "Mapper",
"GUI": "grafisk brukergrensesnitt",
"GUI Authentication Password": "Passord for GUI-autenisering",
"GUI Authentication User": "Bruker for GUI-autenisering",
"GUI Listen Addresses": "GUI Lytteadresse",
"GUI Theme": "GUI tema",
"GUI Listen Addresses": "GUI-lytteadresse",
"GUI Theme": "GUI-tema",
"Generate": "Generer",
"Global Changes": "Globale endringer",
"Global Discovery": "Globalt oppslag",
@@ -97,15 +101,15 @@
"Home page": "Hjemmeside",
"Ignore": "Ignorer",
"Ignore Patterns": "Utelatelsesmønster",
"Ignore Permissions": "Ignorer Tilgangsbit",
"Ignore Permissions": "Ignorer rettigheter",
"Incoming Rate Limit (KiB/s)": "Innkommende hastighetsbegrensning (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Feilaktige innstillinger kan skade innholdet i dine delte kataloger og hindre Syncthing i å fungere.",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Feilaktige innstillinger kan skade innholdet i dine delte mapper og hindre Syncthing i å fungere.",
"Introduced By": "Introdusert av",
"Introducer": "Introduktør",
"Inversion of the given condition (i.e. do not exclude)": "Invers av den gitte tilstanden (t.d. ikke ekskluder)",
"Keep Versions": "Behold versjoner",
"Largest First": "Største fil først",
"Last File Received": "Siste mottatte fil",
"Last File Received": "Sist mottatte fil",
"Last Scan": "Siste gjennomsøking",
"Last seen": "Sist sett",
"Later": "Senere",
@@ -134,22 +138,22 @@
"OK": "OK",
"Off": "Av",
"Oldest First": "Den eldste først",
"Optional descriptive label for the folder. Can be different on each device.": "Valgfri merkelapp på katalogen. Denne kan være ulik på forskjellige enheter",
"Optional descriptive label for the folder. Can be different on each device.": "Valgfri merkelapp på mappa. Denne kan være ulik på forskjellige enheter",
"Options": "Valg",
"Out of Sync": "Ikke synkronisert",
"Out of Sync Items": "Ikke synkroniserte element",
"Out of Sync Items": "Usynkroniserte elementer",
"Outgoing Rate Limit (KiB/s)": "Utgående hastighetsbegrensning (KiB/s)",
"Override Changes": "Overstyr endringer",
"Path": "Sti",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Plasseringen av mappen på datamaskinen. Denne vil bli opprettet dersom den ikke finnes. Krøllstrektegnet (~) kan brukes som forkortelse for",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Plasseringen for lagrede versjoner (la denne være tom for å bruke den forvalgte .stversions-mappa i den delte mappa).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Plasseringen for lagrede versjoner (la denne være tom for å bruke standard .stversions-mappen i mappen).",
"Pause": "Oppholde",
"Pause All": "Sett alt på pause",
"Paused": "Oppholdt",
"Please consult the release notes before performing a major upgrade.": "Se \"release notes\" før en storoppgradering utføres.",
"Please consult the release notes before performing a major upgrade.": "Sjekk utgivelsesnotatene før en storoppgradering utføres.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Vennligst angi bruker og passord for GUI-autentisering i innstillingsvinduet.",
"Please wait": "Vennligst vent",
"Please wait": "Vent",
"Preview": "Forhåndsvisning",
"Preview Usage Report": "Forhåndsvisning av datainnsamling",
"Quick guide to supported patterns": "Kjapp innføring i godkjente mønster",
@@ -160,7 +164,7 @@
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Utgivelseskandidater inneholder de seneste problemfiksene og funksjonene. De ligner på de tradisjonelle Syncthing-utgivelsene som kom hver andre uke.",
"Remote Devices": "Andre enheter",
"Remove": "Fjern",
"Required identifier for the folder. Must be the same on all cluster devices.": "Påkrevd identifikator for katalogen. Denne må være lik på alle enheter i samme klynge.",
"Required identifier for the folder. Must be the same on all cluster devices.": "Påkrevd identifikator for mappa. Denne må være lik på alle enheter i samme klynge.",
"Rescan": "Gjennomsøk på nytt",
"Rescan All": "Gjennomsøk alt på nytt",
"Rescan Interval": "Intervall for gjennomsøking",
@@ -176,18 +180,18 @@
"Select the devices to share this folder with.": "Velg enhetene du vil dele denne mappen med.",
"Select the folders to share with this device.": "Velg hvilke mapper som skal deles med denne enheten.",
"Send & Receive": "Sende og motta",
"Send Only": "Bare sende",
"Send Only": "Bare send",
"Settings": "Innstillinger",
"Share": "Del",
"Share Folder": "Del mappe",
"Share Folders With Device": "Del mapper med enhet",
"Share With Devices": "Del med enheter",
"Share this folder?": "Dele denne mappen?",
"Share this folder?": "Del denne mappa?",
"Shared With": "Delt med",
"Show ID": "Vis ID",
"Show QR": "Vis QR kode",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Vis i stedet for enhets ID i gruppestatus. Vil bli kringkastet til andre enheter som et valgfritt standardnavn.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Vist i stedet for mappe ID i gruppestatus. Vil bli oppdatert til navnet enheten kringkaster dersom tomt.",
"Show QR": "Vis QR-kode",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Vis i stedet for enhets-ID i gruppestatus. Vil bli kringkastet til andre enheter som et valgfritt forvalgsnavn.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Vist i stedet for mappe-ID i gruppestatus. Vil bli oppdatert til navnet enheten kringkaster dersom tomt.",
"Shutdown": "Avslutt",
"Shutdown Complete": "Avslutning fullført",
"Simple File Versioning": "Enkel versjonskontroll",
@@ -197,10 +201,10 @@
"Stable releases and release candidates": "Ferdige utgaver og utgivelseskandidater",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Ferdige utgaver blir holdt tilbake i to uker. I løpet av denne tiden blir de testet som utgivelseskandidater.",
"Stable releases only": "Bare ferdige utgaver",
"Staggered File Versioning": "Forskjøvet Versjonskontroll",
"Staggered File Versioning": "Forskjøvet versjonskontroll",
"Start Browser": "Start nettleser",
"Statistics": "Statistikk",
"Stopped": "Stoppa",
"Stopped": "Stoppet",
"Support": "Brukerstøtte",
"Sync Protocol Listen Addresses": "Lytteadresse for synkroniseringsprotokoll",
"Syncing": "Synkroniserer",
@@ -209,19 +213,19 @@
"Syncthing is restarting.": "Syncthing starter på ny.",
"Syncthing is upgrading.": "Syncthing oppgraderer.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing ser ut til å være nede, eller så er det et problem med nettforbindelsen din. Prøver på ny …",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing ser ut til å ha støtt på et problem under behandling av din forespørsel. Vennligst oppfrisk nettleseren eller start Syncthing på nytt dersom problemet vedvarer.",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing ser ut til å ha støtt på et problem under behandling av din forespørsel. Gjenoppfrisk nettleseren eller start Syncthing på nytt dersom problemet vedvarer.",
"The Syncthing admin interface is configured to allow remote access without a password.": "Grensesnittet for administrering av Syncthing er satt til å tillate ekstern tilgang uten et passord.",
"The aggregated statistics are publicly available at the URL below.": "Samlet statistikk er åpent tilgjengelig via URL som er angitt under",
"The aggregated statistics are publicly available at the URL below.": "Innsamlet statistikk er åpent tilgjengelig via nettadressen angitt nedenfor.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Innstillingene har blitt lagret men ikke aktivert. Syncthing må starte på ny for å aktivere de nye innstillingene.",
"The device ID cannot be blank.": "Enhets-ID kan ikke være tom.",
"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).": "Enhets id som skal skrives her kan du finne i menyen \"Handlinger\" > \"Vis id\" på den andre enheten. Mellomrom og strek er valgfritt (ignoreres)",
"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).": "Enhets-ID som skal skrives her kan du finne i menyen \"Handlinger\" > \"Vis ID\" på den andre enheten. Mellomrom og strek er valgfritt (ignoreres)",
"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.": "Kryptert informasjon om bruken av programmet blir gjort daglig. Dette blir brukt til å følge med på vanlig brukte systemoppsett, størrelser på mapper, og versjoner av programmet. Om datasettet endrer seg vil denne dialogboksen dukke opp og du vil bli bedt om å godkjenne dette.",
"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.": "IDen for denne enheten er ikke godkjent. Det bør være 52 eller 56 tegn bestående av bokstaver og tall, valgfritt med mellomrom og bindestrek.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "Den første kommandolinje-parameteren er katalog-filbanen, det andre parametere er den relative filbanen i katalogen.",
"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.": "ID-en for denne enheten er ikke godkjent. Det bør være 52 eller 56 tegn bestående av bokstaver og tall, valgfritt med mellomrom og bindestrek.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "Den første kommandolinje-parameteren er mappeplasseringen, det andre parameteret er den relative filbanen i mappa.",
"The folder ID cannot be blank.": "Mappe-ID kan ikke være tom.",
"The folder ID must be unique.": "Mappe-ID må være unik.",
"The folder path cannot be blank.": "Mappeplasseringen kan ikke være tom.",
"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.": "Følgende intervall blir brukt: den første timen blir en versjon lagret hvert 30. sekund, den første dagen blir en versjon lagret hver time, de første 30 dagene blir en versjon lagret hver dag, og inntil maksimal levetid blir en versjon lagret hver uke.",
"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.": "Følgende intervall blir brukt: Den første timen blir en versjon lagret hvert 30. sekund, den første dagen blir en versjon lagret hver time, de første 30 dagene blir en versjon lagret hver dag, og inntil maksimal levetid blir en versjon lagret hver uke.",
"The following items could not be synchronized.": "Følgende filer kunne ikke synkroniseres.",
"The maximum age must be a number and cannot be blank.": "Maksimal levetid må være et tall og kan ikke være tomt.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maksimal tid å beholde en versjon (i dager, sett til 0 for å beholde versjoner på ubegrenset tid).",
@@ -255,10 +259,10 @@
"Version": "Versjon",
"Versions Path": "Plassering av versjoner",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versjoner blir automatisk slettet når maksimal levetid er nådd eller når antall filer er oversteget.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Advarsel, denne stien er en foreldrekatalog for en eksisterende mappe \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Advarsel, denne stien er en foreldrekatalog for en eksisterende mappe \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Advarsel, denne stien er en underkatalog i en eksisterende katalog \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Advarsel, denne stien er en underkatalog for en eksisterende mappe \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Advarsel, denne stien er en foreldremappe for en eksisterende mappe \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Advarsel, denne stien er en foreldremappe for en eksisterende mappe \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Advarsel, denne stien er en undermappe i en eksisterende mappe \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Advarsel, denne stien er en undermappe for en eksisterende mappe \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Merk at når en ny enhet blir lagt til må denne også legges til på andre siden.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Når en ny mappe blir lagt til, husk at Mappe-ID blir brukt til å binde sammen mapper mellom enheter. Det er forskjell på store og små bokstaver, så IDene må være identiske på alle enhetene.",
"Yes": "Ja",
@@ -266,10 +270,10 @@
"You can read more about the two release channels at the link below.": "Du kan lese mer om de to nye utgivelseskanalene i lenken nedenfor.",
"You must keep at least one version.": "Du må beholde minst én versjon",
"days": "dager",
"directories": "kataloger",
"directories": "mapper",
"files": "filer",
"full documentation": "all dokumentasjon",
"items": "elementer",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønsker å dele mappen \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} ønsker å dele katalogen \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønsker å dele mappa \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} ønsker å dele mappa \"{{folderlabel}}\" ({{folder}})."
}
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Geavanceerde instellingen",
"All Data": "Alle gegevens",
"Allow Anonymous Usage Reporting?": "Versturen van anonieme gebruikersstatistieken toestaan?",
"Allowed Networks": "Toegestane netwerken",
"Alphabetic": "Alfabetisch",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Een extern commando regelt het versiebeheer. Dit moet het bestand verwijderen van de gedeelde map.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Een extern commando regelt het versiebeheer. Dit moet het bestand verwijderen van de gesynchroniseerde map.",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU-gebruik",
"Changelog": "Logboek",
"Clean out after": "Schoon op na",
"Click to see discovery failures": "Klik om ontdekkingsproblemen weer te geven",
"Close": "Sluiten",
"Command": "Commando",
"Comment, when used at the start of a line": "Reageer indien gebruikt aan het begin van een lijn.",
@@ -41,6 +43,7 @@
"Copied from original": "Gekopieerd van het origineel",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 voor de volgende bijdragers:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 de volgende bijdragers:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Negeerpatronen worden aangemaakt, bestaand bestand wordt overschreven op {{path}}.",
"Danger!": "Let op!",
"Deleted": "Verwijderd",
"Device": "Apparaat",
@@ -61,6 +64,7 @@
"Edit Device": "Bewerk apparaat",
"Edit Folder": "Bewerk map",
"Editing": "Bezig met bewerken",
"Editing {%path%}.": "Bezig met bewerken van {{path}}.",
"Enable NAT traversal": "Activeer NAT traversal",
"Enable Relaying": "Activeer doorsturen",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Voer door komma's gescheiden (\"tcp://ip:port\", \"tcp://host:port\") adressen in of voer \"dynamisch\" in om automatische ontdekking van het adres uit te voeren.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Avanserte innstillingar",
"All Data": "Alle data",
"Allow Anonymous Usage Reporting?": "Tillata anonymisert bruksrapportering?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabetisk",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Ein ekstern kommando handterer filutgåver. Den må sørga for at fila blir fjerna frå den synkroniserte mappa.",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU-utnytting",
"Changelog": "Endringslogg",
"Clean out after": "Tøm etter",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Lukk",
"Command": "Kommando",
"Comment, when used at the start of a line": "Kommentar, når brukt i starten av linja",
@@ -41,6 +43,7 @@
"Copied from original": "Kopiert frå originalen",
"Copyright © 2014-2016 the following Contributors:": "Opphavsrett © 2014-2016 for følgjande bidragsyterar:",
"Copyright © 2014-2017 the following Contributors:": "Opphavsrett © 2014-2017 for følgjande bidragsyterar:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Fare!",
"Deleted": "Sletta",
"Device": "Eining",
@@ -61,6 +64,7 @@
"Edit Device": "Rediger enhet",
"Edit Folder": "Rediger katalog",
"Editing": "Redigerer",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Slå på NAT-gjennomgang",
"Enable Relaying": "Aktiver relé",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Skriv inn adresser med komma mellom kvar adresse («tcp://ip:port», «tcp://host:port»), eller «dynamic» for å automatisk søkja opp adressa.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Ustawienia zaawansowane",
"All Data": "Wszystkie dane",
"Allow Anonymous Usage Reporting?": "Zezwalaj na anonimowe statystyki użycia?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabetycznie",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Zewnętrzna komenda obsługuje kontrolę wersji. Musi ona usunąć ten plik z synchronizowanego folderu.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Użycie CPU",
"Changelog": "Historia zmian",
"Clean out after": "Uporządkuj",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Zamknij",
"Command": "Polecenie",
"Comment, when used at the start of a line": "Komentarz, jeżeli użyty na początku linii",
@@ -41,6 +43,7 @@
"Copied from original": "Skopiowane z oryginału",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016: ",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Niebezpieczne!",
"Deleted": "Usunięto",
"Device": "Urządzenie",
@@ -61,6 +64,7 @@
"Edit Device": "Edytuj urządzenie",
"Edit Folder": "Edytuj folder",
"Editing": "Edytowanie",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Włącz trawersowanie NAT",
"Enable Relaying": "Włącz przekazywanie",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Wpisz oddzielone przecinkiem adresy (\"tcp://ip:port\", \"tcp://host:port\") lub \"dynamic\" by przeprowadzić automatyczne odnalezienie adresu.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Configurações avançadas",
"All Data": "Todos os dados",
"Allow Anonymous Usage Reporting?": "Permitir envio de relatórios anônimos de uso?",
"Allowed Networks": "Redes permitidas",
"Alphabetic": "Alfabética",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Um comando externo cuida do versionamento. Ele tem que remover o arquivo da pasta compartilhada.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Um programa externo controla o versionamento. Ele tem que remover o arquivo da pasta sincronizada.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Uso de CPU",
"Changelog": "Registro de alterações",
"Clean out after": "Limpar depois de",
"Click to see discovery failures": "Clique para ver as falhas na descoberta de dispositivos",
"Close": "Fechar",
"Command": "Comando",
"Comment, when used at the start of a line": "Comentário, se usado no início de uma linha",
@@ -41,6 +43,7 @@
"Copied from original": "Copiado do original",
"Copyright © 2014-2016 the following Contributors:": "Direitos reservados © 2014-2016 aos seguintes colaboradores:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 dos seguintes Colaboradores:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Perigo!",
"Deleted": "Apagado",
"Device": "Dispositivo",
@@ -61,6 +64,7 @@
"Edit Device": "Editar dispositivo",
"Edit Folder": "Editar pasta",
"Editing": "Editando",
"Editing {%path%}.": "Editando {{path}}.",
"Enable NAT traversal": "Habilitar NAT",
"Enable Relaying": "Habilitar retransmissão",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Insira endereços (\"tcp://ip:porta\", \"tcp://host:porta\") separados por vírgula ou \"dynamic\" para executar a descoberta automática do endereço.",
+7 -3
View File
@@ -1,5 +1,5 @@
{
"A device with that ID is already added.": "Já tinha sido adicionado um dispositivo com esse ID.",
"A device with that ID is already added.": "Já foi adicionado um dispositivo com esse ID anteriormente.",
"A negative number of days doesn't make sense.": "Um número negativo de dias não faz sentido.",
"A new major version may not be compatible with previous versions.": "Uma nova versão principal pode não ser compatível com versões anteriores.",
"API Key": "Chave da API",
@@ -18,6 +18,7 @@
"Advanced settings": "Configurações avançadas",
"All Data": "Todos os dados",
"Allow Anonymous Usage Reporting?": "Permitir envio de relatórios anónimos de utilização?",
"Allowed Networks": "Redes permitidas",
"Alphabetic": "Alfabética",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Um comando externo controla as versões. Esse comando tem que remover o ficheiro da pasta partilhada.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Um comando externo trata do controle de versões. Esse comando tem que remover o ficheiro da pasta sincronizada.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Utilização da CPU",
"Changelog": "Registo de alterações",
"Clean out after": "Esvaziar ao fim de",
"Click to see discovery failures": "Clique para ver as falhas da pesquisa",
"Close": "Fechar",
"Command": "Comando",
"Comment, when used at the start of a line": "Comentário, quando usado no início de uma linha",
@@ -41,6 +43,7 @@
"Copied from original": "Copiado do original",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 os seguintes contribuidores:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 dos seguintes contribuidores:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Criando padrões de exclusão, sobrescrevendo um ficheiro existente em {{path}}.",
"Danger!": "Perigo!",
"Deleted": "Eliminado",
"Device": "Dispositivo",
@@ -52,7 +55,7 @@
"Disconnected": "Desconectado",
"Discovered": "Descoberto",
"Discovery": "Pesquisa",
"Discovery Failures": "Falhas na pesquisa",
"Discovery Failures": "Falhas da pesquisa",
"Documentation": "Documentação",
"Download Rate": "Velocidade de recepção",
"Downloaded": "Recebido",
@@ -61,6 +64,7 @@
"Edit Device": "Editar dispositivo",
"Edit Folder": "Editar pasta",
"Editing": "Editando",
"Editing {%path%}.": "Editando {{path}}.",
"Enable NAT traversal": "Activar travessia de NAT",
"Enable Relaying": "Permitir retransmissão",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduza endereços separados por vírgulas (\"tcp://ip:porto\", \"tcp://máquina:porto\") ou \"dynamic\" para detectar automaticamente os endereços.",
@@ -68,7 +72,7 @@
"Error": "Erro",
"External File Versioning": "Externa",
"Failed Items": "Itens que falharam",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "São esperadas falhas na ligação a servidores IPv6 se não existir conexão IPv6.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "São esperadas falhas na ligação a servidores IPv6 se não existir conectividade IPv6.",
"File Pull Order": "Ordem de obtenção de ficheiros",
"File Versioning": "Gestão de versões de ficheiros",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "As permissões do ficheiro são ignoradas ao procurar alterações. Utilize nos sistemas de ficheiros FAT.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Дополнительные настройки",
"All Data": "Все данные",
"Allow Anonymous Usage Reporting?": "Разрешить анонимный отчет об использовании?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "По алфавиту",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Внешний процесс управляет версиями файлов. Процесс удалит файл из синхронизируемой папки.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Загрузка ЦП",
"Changelog": "Журнал изменений",
"Clean out after": "Очистить после",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Закрыть",
"Command": "Команда",
"Comment, when used at the start of a line": "Комментарий, если используется в начале строки",
@@ -41,6 +43,7 @@
"Copied from original": "Скопировано с оригинала",
"Copyright © 2014-2016 the following Contributors:": "Авторские права © 2014–2016 принадлежат:",
"Copyright © 2014-2017 the following Contributors:": "Авторское право © 2014-2017 следующие участники:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Опасно!",
"Deleted": "Удалено",
"Device": "Устройство",
@@ -61,6 +64,7 @@
"Edit Device": "Редактирование устройства",
"Edit Folder": "Редактирование папки",
"Editing": "Редактирование",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Включить NAT traversal",
"Enable Relaying": "Включить релеи",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Введите через запятую («tcp://ip:port», «tcp://host:port») адреса, либо «dynamic», чтобы выполнить автоматическое обнаружение адреса.",
+9 -5
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Avancerade inställningar",
"All Data": "All data",
"Allow Anonymous Usage Reporting?": "Tillåt anonym användarstatistiksrapportering?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabetisk",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Ett externt kommando hanterar versionshanteringen. Det måste ta bort filen från den delade katalogen.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Ett externt kommando sköter versionshanteringen. Den behöver ta bort filen från den synkroniserade katalogen.",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU användning",
"Changelog": "Ändringslogg",
"Clean out after": "Rensa efteråt",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Stäng",
"Command": "Kommando",
"Comment, when used at the start of a line": "Kommentara, vid användning i början av en rad.",
@@ -41,8 +43,9 @@
"Copied from original": "Kopierat från original",
"Copyright © 2014-2016 the following Contributors:": "Upphovsrätt © 2014-2016 följande bidragare:",
"Copyright © 2014-2017 the following Contributors:": "Upphovsrätt © 2014-2017 följande bidragande:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Fara!",
"Deleted": "Raderade",
"Deleted": "Tog bort",
"Device": "Enhet",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Enhet \"{{name}}\" ({{device}} på {{address}}) vill ansluta. Lägg till ny enhet?",
"Device ID": "Enhet-ID",
@@ -52,7 +55,7 @@
"Disconnected": "Frånkopplad",
"Discovered": "Upptäckt",
"Discovery": "Annonsering",
"Discovery Failures": "Discovery Failures",
"Discovery Failures": "Upptäcktsmisslyckanden",
"Documentation": "Dokumentation",
"Download Rate": "Nedladdningshastighet",
"Downloaded": "Hämtat",
@@ -61,6 +64,7 @@
"Edit Device": "Redigera enhet",
"Edit Folder": "Redigera katalog",
"Editing": "Redigerar",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Aktivera NAT traversering",
"Enable Relaying": "Aktivera reläa",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Ange kommaseparerade (\"tcp://ip:port\", \"tcp://host:port\")-adresser eller ordet \"dynamic\" för att använda automatisk uppslagning.",
@@ -68,14 +72,14 @@
"Error": "Fel",
"External File Versioning": "Extern filversionshantering",
"Failed Items": "Misslyckade objekt",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Misslyckande med att ansluta till IPv6-servrar förväntas om ingen IPv6-anslutning finns.",
"File Pull Order": "Filhämtningsprioritering",
"File Versioning": "Filversionshantering",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Filrättigheter ignoreras under sökning efter förändringar. Används på FAT-filsystem.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Filer flyttas till .stversions-katalog vid byte eller tas bort av Syncthing.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Filer flyttas till .stversions katalogen när de ersätts eller raderas av Syncthing.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Filer flyttas till .stversions katalogen när de ersätts eller tas bort av Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Filer flyttas till datumstämplade versioner i en .stversions-katalog när de ersätts eller tas bort av Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Filer flyttas till datummärkta versioner i en .stversions katalog när de ersätts eller raderas av Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Filer flyttas till datummärkta versioner i en .stversions katalog när de ersätts eller tas bort av 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.": "Filer skyddas från ändringar gjorda på andra enheter, men ändringar som görs på den här noden skickas till de andra klustermedlemmarna.",
"Folder": "Katalog",
"Folder ID": "Katalog-ID",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Gelişmiş ayarlar",
"All Data": "Tüm Veriler",
"Allow Anonymous Usage Reporting?": "Anonim kullanımın raporlanmasına izin veriyor musun ?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabetik",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Sürümleme işlemini harici bir komut yürütüyor. Dosyayı eşzamanlama klasöründen kaldırmak zorunda.",
@@ -30,6 +31,7 @@
"CPU Utilization": "İşlemci Kullanımı",
"Changelog": "Değişim Günlüğü",
"Clean out after": "Şundan sonra temizle",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Kapat",
"Command": "Komut",
"Comment, when used at the start of a line": "Satır başında kullanıldığında açıklama özelliği taşır",
@@ -41,6 +43,7 @@
"Copied from original": "Aslından kopyalanmış",
"Copyright © 2014-2016 the following Contributors:": "Telif Hakkı © 2014-2016 takip eden Katkıcılar:",
"Copyright © 2014-2017 the following Contributors:": "Telif Hakkı © 2014-2017 takip eden Katkıcılar:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Tehlike!",
"Deleted": "Silindi",
"Device": "Aygıt",
@@ -61,6 +64,7 @@
"Edit Device": "Aygıtı Düzenle",
"Edit Folder": "Klasörü Düzenle",
"Editing": "Düzenleniyor",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "NAT çaprazlamasına izin ver",
"Enable Relaying": "Enable Relaying",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Adreslerin kendiliğinden keşfedilebilmesi için ya adresleri virgülle ayırarak (\"tcp://ip:port\", \"tcp://host:port\") girin, ya da \"dynamic\" sözcüğünü girin.",
+6 -2
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Розширені налаштування",
"All Data": "Усі дані",
"Allow Anonymous Usage Reporting?": "Дозволити програмі збирати анонімну статистику використання?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "За алфавітом",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Зовнішня команда керування версіями. Вона має видалити файл із спільної директорії.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Зовнішня команда керування версіями. Вона має видалити файл із директорії, що синхронізується.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Навантаження CPU",
"Changelog": "Перелік змін",
"Clean out after": "Очистити після",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Закрити",
"Command": "Команда",
"Comment, when used at the start of a line": "Коментар, якщо використовується на початку рядка",
@@ -41,6 +43,7 @@
"Copied from original": "Скопійовано з оригіналу",
"Copyright © 2014-2016 the following Contributors:": "© 2014-2016 Всі права застережено, вклад внесли:",
"Copyright © 2014-2017 the following Contributors:": "© 2014-2017 Всі права застережено, вклад внесли:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Небезпечно!",
"Deleted": "Видалене",
"Device": "Пристрій",
@@ -52,7 +55,7 @@
"Disconnected": "З’єднання відсутнє",
"Discovered": "Виявлено",
"Discovery": "Сервери координації NAT",
"Discovery Failures": "Discovery Failures",
"Discovery Failures": "Помилки виявлення",
"Documentation": "Документація",
"Download Rate": "Швидкість завантаження",
"Downloaded": "Завантажено",
@@ -61,6 +64,7 @@
"Edit Device": "Налаштування пристрою",
"Edit Folder": "Налаштування директорії",
"Editing": "Редагування",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Увімкнути NAT traversal",
"Enable Relaying": "Увімкнути ретрансляцію (relaying)",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Введіть розділені комою (\"tcp://ip:port\", \"tcp://host:port\") адреси або \"dynamic\" для автоматичного визначення адреси.",
@@ -68,7 +72,7 @@
"Error": "Помилка",
"External File Versioning": "Зовнішне керування версіями",
"Failed Items": "Невдалі",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "За відсутності IPv6-з'єднання очікується неможливість підключення до IPv6-серверів.",
"File Pull Order": "Порядок витягнення файлів",
"File Versioning": "Керування версіями",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Біти прав доступу до файлів будуть проігноровані під час пошуку змін. Використовуйте на файлових системах FAT.",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "Cài đặt nâng cao",
"All Data": "Tất cả dữ liệu",
"Allow Anonymous Usage Reporting?": "Cho phép báo cáo sử dụng ẩn danh?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "A-Z",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Một lệnh ngoại vi chịu trách nhiệm phiên bản hoá. Nó sẽ xoá tập tin khỏi thư mục đã đồng bộ.",
@@ -30,6 +31,7 @@
"CPU Utilization": "Mức s.dụng CPU",
"Changelog": "Lịch sử thay đổi",
"Clean out after": "Dọn dẹp sau",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Đóng",
"Command": "Lệnh",
"Comment, when used at the start of a line": "Bình luận, khi dùng trước đầu dòng",
@@ -41,6 +43,7 @@
"Copied from original": "Đã sao chép từ nguồn",
"Copyright © 2014-2016 the following Contributors:": "Bản quyền © 2014-2016 thuộc về các nhà cộng tác sau:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Nguy hiểm!",
"Deleted": "Đã xoá",
"Device": "Device",
@@ -61,6 +64,7 @@
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Editing": "Đang ch.sửa",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Enable NAT traversal",
"Enable Relaying": "Bật chế độ ch.tiếp",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Nhập các địa chỉ ngăn cách bởi dấu phẩy (\"tcp://ip:port\", \"tcp://host:port\") hoặc \"dynamic\" để tiến hành dò tìm địa chỉ tự động.",
+11 -7
View File
@@ -18,6 +18,7 @@
"Advanced settings": "高级设置",
"All Data": "所有数据",
"Allow Anonymous Usage Reporting?": "允许匿名使用报告?",
"Allowed Networks": "允许的网络",
"Alphabetic": "字母顺序",
"An external command handles the versioning. It has to remove the file from the shared folder.": "使用外部命令接管版本控制。该命令必须自行从共享文件夹中删除该文件。",
"An external command handles the versioning. It has to remove the file from the synced folder.": "使用外部命令接管版本控制。该命令必须自行从同步文件夹中删除该文件。",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU使用率",
"Changelog": "更新日志",
"Clean out after": "在该时间后清除:",
"Click to see discovery failures": "点击查看发现错误",
"Close": "关闭",
"Command": "命令",
"Comment, when used at the start of a line": "注释,在行首使用",
@@ -41,6 +43,7 @@
"Copied from original": "从源复制",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 以下贡献者:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 以下贡献者:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "正在创建忽略列表,覆盖位于 {{path}} 的已有文件。",
"Danger!": "危险!",
"Deleted": "已删除",
"Device": "设备",
@@ -51,8 +54,8 @@
"Devices": "设备",
"Disconnected": "连接已断开",
"Discovered": "已发现",
"Discovery": "寻找",
"Discovery Failures": "Discovery Failures",
"Discovery": "发现",
"Discovery Failures": "发现错误",
"Documentation": "文档",
"Download Rate": "下载速度",
"Downloaded": "已下载",
@@ -61,14 +64,15 @@
"Edit Device": "编辑设备",
"Edit Folder": "编辑文件夹",
"Editing": "正在编辑",
"Editing {%path%}.": "正在编辑 {{path}}。",
"Enable NAT traversal": "启用 NAT 遍历",
"Enable Relaying": "开启中继",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "输入以半角逗号分隔的 (\"tcp://ip:port\", \"tcp://host:port\") 设置可用地址列表,或者输入 \"dynamic\" 表示自动寻找地址。",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "输入以半角逗号分隔的 (\"tcp://ip:port\", \"tcp://host:port\") 设置可用地址列表,或者输入 \"dynamic\" 表示自动发现地址。",
"Enter ignore patterns, one per line.": "请输入忽略表达式,每行一条。",
"Error": "错误",
"External File Versioning": "外部版本控制",
"Failed Items": "失败的项目",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "如果无 IPv6 连接则预期连接到 IPv6 服务器会失败。",
"File Pull Order": "文件拉取顺序",
"File Versioning": "版本控制",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "当查找文件更改时,忽略文件权限位。用在 FAT 文件系统上。",
@@ -90,8 +94,8 @@
"GUI Theme": "GUI 主题",
"Generate": "生成",
"Global Changes": "全局更改",
"Global Discovery": "在互联网上寻找设备",
"Global Discovery Servers": "全发现服务器",
"Global Discovery": "全球发现",
"Global Discovery Servers": "全发现服务器",
"Global State": "全局状态",
"Help": "帮助",
"Home page": "主页",
@@ -112,7 +116,7 @@
"Latest Change": "最后更改",
"Learn more": "了解更多",
"Listeners": "侦听程序",
"Local Discovery": "在局域网上寻找设备",
"Local Discovery": "本地发现",
"Local State": "本地状态",
"Local State (Total)": "本地状态汇总",
"Major Upgrade": "重大更新",
+4
View File
@@ -18,6 +18,7 @@
"Advanced settings": "進階設定",
"All Data": "全部資料",
"Allow Anonymous Usage Reporting?": "允許匿名的使用資訊回報?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "字母順序",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
@@ -30,6 +31,7 @@
"CPU Utilization": "CPU 使用",
"Changelog": "更新日誌",
"Clean out after": "於之後清空",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "關閉",
"Command": "指令",
"Comment, when used at the start of a line": "註解,當輸入在一行的開頭時",
@@ -41,6 +43,7 @@
"Copied from original": "從原處複製",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 下列貢獻者:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "危險!",
"Deleted": "已刪除",
"Device": "Device",
@@ -61,6 +64,7 @@
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Editing": "正在編輯",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Enable NAT traversal",
"Enable Relaying": "啟用中繼",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.",
+36 -5
View File
@@ -473,11 +473,23 @@
<tbody>
<tr>
<th><span class="fa fa-fw fa-cloud-download"></span>&nbsp;<span translate>Download Rate</span></th>
<td class="text-right">{{connectionsTotal.inbps | binary}}B/s ({{connectionsTotal.inBytesTotal | binary}}B)</td>
<td class="text-right">
<a href="#" class="toggler" ng-click="toggleUnits()">
<span ng-if="!metricRates">{{connectionsTotal.inbps | binary}}B/s</span>
<span ng-if="metricRates">{{connectionsTotal.inbps*8 | metric}}bps</span>
({{connectionsTotal.inBytesTotal | binary}}B)</span>
</a>
</td>
</tr>
<tr>
<th><span class="fa fa-fw fa-cloud-upload"></span>&nbsp;<span translate>Upload Rate</span></th>
<td class="text-right">{{connectionsTotal.outbps | binary}}B/s ({{connectionsTotal.outBytesTotal | binary}}B)</td>
<td class="text-right">
<a href="#" class="toggler" ng-click="toggleUnits()">
<span ng-if="!metricRates">{{connectionsTotal.outbps | binary}}B/s</span>
<span ng-if="metricRates">{{connectionsTotal.outbps*8 | metric}}bps</span>
({{connectionsTotal.outBytesTotal | binary}}B)
</a>
</td>
</tr>
<tr>
<th><span class="fa fa-fw fa-home"></span>&nbsp;<span translate>Local State (Total)</span></th>
@@ -511,7 +523,7 @@
<span>{{discoveryTotal}}/{{discoveryTotal}}</span>
</span>
<span ng-if="discoveryFailed.length != 0" class="data" ng-class="{'text-danger': discoveryFailed.length == discoveryTotal}">
<span popover data-trigger="hover" data-placement="bottom" data-content="Click to see discovery failures.">
<span popover data-trigger="hover" data-placement="bottom" data-content="{{'Click to see discovery failures' | translate}}.">
<a href="" style="color:inherit" ng-click="showDiscoveryFailures()">{{discoveryTotal-discoveryFailed.length}}/{{discoveryTotal}}</a>
</span>
</span>
@@ -559,11 +571,23 @@
<tbody>
<tr ng-if="connections[deviceCfg.deviceID].connected">
<th><span class="fa fa-fw fa-cloud-download"></span>&nbsp;<span translate>Download Rate</span></th>
<td class="text-right">{{connections[deviceCfg.deviceID].inbps | binary}}B/s ({{connections[deviceCfg.deviceID].inBytesTotal | binary}}B)</td>
<td class="text-right">
<a href="#" class="toggler" ng-click="toggleUnits()">
<span ng-if="!metricRates">{{connections[deviceCfg.deviceID].inbps | binary}}B/s</span>
<span ng-if="metricRates">{{connections[deviceCfg.deviceID].inbps*8 | metric}}bps</span>
({{connections[deviceCfg.deviceID].inBytesTotal | binary}}B)</span>
</a>
</td>
</tr>
<tr ng-if="connections[deviceCfg.deviceID].connected">
<th><span class="fa fa-fw fa-cloud-upload"></span>&nbsp;<span translate>Upload Rate</span></th>
<td class="text-right">{{connections[deviceCfg.deviceID].outbps | binary}}B/s ({{connections[deviceCfg.deviceID].outBytesTotal | binary}}B)</td>
<td class="text-right">
<a href="#" class="toggler" ng-click="toggleUnits()">
<span ng-if="!metricRates">{{connections[deviceCfg.deviceID].outbps | binary}}B/s</span>
<span ng-if="metricRates">{{connections[deviceCfg.deviceID].outbps*8 | metric}}bps</span>
({{connections[deviceCfg.deviceID].outBytesTotal | binary}}B)</span>
</a>
</td>
</tr>
<tr>
<th><span class="fa fa-fw fa-link"></span>&nbsp<span translate>Address</span></th>
@@ -581,6 +605,12 @@
<th><span class="fa fa-fw fa-warning text-danger"></span>&nbsp;<span translate>Connection Type</span></th>
<td class="text-right">{{connections[deviceCfg.deviceID].type}}</td>
</tr>
<tr ng-if="deviceCfg.allowedNetworks">
<th><span class="fa fa-fw fa-filter"></span>&nbsp;<span translate>Allowed Networks</span></th>
<td class="text-right">
<span>{{deviceCfg.allowedNetworks.join(", ")}}</span>
</td>
</tr>
<tr ng-if="deviceCfg.compression != 'metadata'">
<th><span class="fa fa-fw fa-compress"></span>&nbsp;<span translate>Compression</span></th>
<td class="text-right">
@@ -705,6 +735,7 @@
<script src="syncthing/core/localeService.js"></script>
<script src="syncthing/core/modalDirective.js"></script>
<script src="syncthing/core/naturalFilter.js"></script>
<script src="syncthing/core/metricFilter.js"></script>
<script src="syncthing/core/notificationDirective.js"></script>
<script src="syncthing/core/pathIsSubDirDirective.js"></script>
<script src="syncthing/core/popoverDirective.js"></script>
+1 -1
View File
@@ -1,7 +1,7 @@
angular.module('syncthing.core')
.filter('binary', function () {
return function (input) {
if (input === undefined) {
if (input === undefined || isNaN(input)) {
return '0 ';
}
if (input > 1024 * 1024 * 1024) {
@@ -0,0 +1,21 @@
angular.module('syncthing.core')
.filter('metric', function () {
return function (input) {
if (input === undefined || isNaN(input)) {
return '0 ';
}
if (input > 1000 * 1000 * 1000) {
input /= 1000 * 1000 * 1000;
return input.toFixed(decimals(input, 2)) + ' G';
}
if (input > 1000 * 1000) {
input /= 1000 * 1000;
return input.toFixed(decimals(input, 2)) + ' M';
}
if (input > 1000) {
input /= 1000;
return input.toFixed(decimals(input, 2)) + ' k';
}
return Math.round(input) + ' ';
};
});
@@ -52,6 +52,11 @@ angular.module('syncthing.core')
$scope.scanProgress = {};
$scope.themes = [];
$scope.globalChangeEvents = {};
$scope.metricRates = false;
try {
$scope.metricRates = (window.localStorage["metricRates"] == "true");
} catch (exception) { }
$scope.localStateTotal = {
bytes: 0,
@@ -1743,6 +1748,9 @@ angular.module('syncthing.core')
if (typeof value === 'boolean') {
return 'checkbox';
}
if (value instanceof Array) {
return 'list';
}
if (typeof value === 'object') {
return 'skip';
}
@@ -1756,7 +1764,6 @@ angular.module('syncthing.core')
};
$scope.modalLoaded = function () {
// once all modal elements have been processed
if ($('modal').length === 0) {
@@ -1765,4 +1772,10 @@ angular.module('syncthing.core')
}
}
$scope.toggleUnits = function () {
$scope.metricRates = !$scope.metricRates;
try {
window.localStorage["metricRates"] = $scope.metricRates;
} catch (exception) { }
}
});
@@ -40,7 +40,7 @@
<label>
<input type="checkbox" ng-model="currentDevice.introducer"> <span translate>Introducer</span>
</label>
<p translate class="help-block">Any devices configured on an introducer device will be added to this device as well.</p>
<p translate class="help-block">Add devices from the introducer to our device list, for mutually shared folders.</p>
</div>
</div>
<div class="row">
@@ -18,7 +18,8 @@
<div ng-repeat="(key, value) in advancedConfig.gui" ng-init="type = inputTypeFor(key, value)" ng-if="type != 'skip'" class="form-group">
<label for="guiInput{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<div class="col-sm-8">
<input id="guiInput{{$index}}" class="form-control" type="{{type}}" ng-model="advancedConfig.gui[key]" />
<input ng-if="inputTypeFor(key, value) == 'list'" id="optionsInput{{$index}}" class="form-control" type="text" ng-model="advancedConfig.gui[key]" ng-list/>
<input ng-if="inputTypeFor(key, value) != 'list'" id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="advancedConfig.gui[key]" />
</div>
</div>
</form>
@@ -36,7 +37,8 @@
<div ng-repeat="(key, value) in advancedConfig.options" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="optionsInput{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<div class="col-sm-8">
<input id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="advancedConfig.options[key]" />
<input ng-if="inputTypeFor(key, value) == 'list'" id="optionsInput{{$index}}" class="form-control" type="text" ng-model="advancedConfig.options[key]" ng-list/>
<input ng-if="inputTypeFor(key, value) != 'list'" id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="advancedConfig.options[key]" />
</div>
</div>
</form>
@@ -59,7 +61,29 @@
<div ng-repeat="(key, value) in folder" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="folder{{$index}}Input{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<div class="col-sm-8">
<input id="folder{{$index}}Input{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="folder[key]" />
<input ng-if="inputTypeFor(key, value) == 'list'" id="optionsInput{{$index}}" class="form-control" type="text" ng-model="folder[key]" ng-list/>
<input ng-if="inputTypeFor(key, value) != 'list'" id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="folder[key]" />
</div>
</div>
</form>
</div>
</div>
</div>
<div class="panel panel-default" ng-repeat="device in advancedConfig.devices">
<div class="panel-heading" role="tab" id="device{{$index}}Heading" data-toggle="collapse" data-parent="#advancedAccordion" href="#device{{$index}}Config" aria-expanded="false" aria-controls="folder{{$index}}Config" style="cursor: pointer;">
<h4 class="panel-title" tabindex="0">
<span translate>Device</span> "{{deviceName(device)}}"
</h4>
</div>
<div id="device{{$index}}Config" class="panel-collapse collapse" role="tabpanel" aria-labelledby="device{{$index}}Heading">
<div class="panel-body">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in device" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="device{{$index}}Input{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<div class="col-sm-8">
<input ng-if="inputTypeFor(key, value) == 'list'" id="optionsInput{{$index}}" class="form-control" type="text" ng-model="device[key]" ng-list/>
<input ng-if="inputTypeFor(key, value) != 'list'" id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="device[key]" />
</div>
</div>
</form>
@@ -76,7 +100,7 @@
<span class="fa fa-times"></span>&nbsp;<span translate>Close</span>
</button>
</div>
</div>
</modal>
+1 -5
View File
@@ -315,12 +315,8 @@ func (cfg *Configuration) clean() error {
sort.Sort(FolderDeviceConfigurationList(cfg.Folders[i].Devices))
}
// An empty address list is equivalent to a single "dynamic" entry
for i := range cfg.Devices {
n := &cfg.Devices[i]
if len(n.Addresses) == 0 || len(n.Addresses) == 1 && n.Addresses[0] == "" {
n.Addresses = []string{"dynamic"}
}
cfg.Devices[i].prepare()
}
// Very short reconnection intervals are annoying
+55 -41
View File
@@ -133,16 +133,18 @@ func TestDeviceConfig(t *testing.T) {
expectedDevices := []DeviceConfiguration{
{
DeviceID: device1,
Name: "node one",
Addresses: []string{"tcp://a"},
Compression: protocol.CompressMetadata,
DeviceID: device1,
Name: "node one",
Addresses: []string{"tcp://a"},
Compression: protocol.CompressMetadata,
AllowedNetworks: []string{},
},
{
DeviceID: device4,
Name: "node two",
Addresses: []string{"tcp://b"},
Compression: protocol.CompressMetadata,
DeviceID: device4,
Name: "node two",
Addresses: []string{"tcp://b"},
Compression: protocol.CompressMetadata,
AllowedNetworks: []string{},
},
}
expectedDeviceIDs := []protocol.DeviceID{device1, device4}
@@ -236,22 +238,26 @@ func TestDeviceAddressesDynamic(t *testing.T) {
name, _ := os.Hostname()
expected := map[protocol.DeviceID]DeviceConfiguration{
device1: {
DeviceID: device1,
Addresses: []string{"dynamic"},
DeviceID: device1,
Addresses: []string{"dynamic"},
AllowedNetworks: []string{},
},
device2: {
DeviceID: device2,
Addresses: []string{"dynamic"},
DeviceID: device2,
Addresses: []string{"dynamic"},
AllowedNetworks: []string{},
},
device3: {
DeviceID: device3,
Addresses: []string{"dynamic"},
DeviceID: device3,
Addresses: []string{"dynamic"},
AllowedNetworks: []string{},
},
device4: {
DeviceID: device4,
Name: name, // Set when auto created
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
DeviceID: device4,
Name: name, // Set when auto created
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
AllowedNetworks: []string{},
},
}
@@ -270,25 +276,29 @@ func TestDeviceCompression(t *testing.T) {
name, _ := os.Hostname()
expected := map[protocol.DeviceID]DeviceConfiguration{
device1: {
DeviceID: device1,
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
DeviceID: device1,
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
AllowedNetworks: []string{},
},
device2: {
DeviceID: device2,
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
DeviceID: device2,
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
AllowedNetworks: []string{},
},
device3: {
DeviceID: device3,
Addresses: []string{"dynamic"},
Compression: protocol.CompressNever,
DeviceID: device3,
Addresses: []string{"dynamic"},
Compression: protocol.CompressNever,
AllowedNetworks: []string{},
},
device4: {
DeviceID: device4,
Name: name, // Set when auto created
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
DeviceID: device4,
Name: name, // Set when auto created
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
AllowedNetworks: []string{},
},
}
@@ -307,22 +317,26 @@ func TestDeviceAddressesStatic(t *testing.T) {
name, _ := os.Hostname()
expected := map[protocol.DeviceID]DeviceConfiguration{
device1: {
DeviceID: device1,
Addresses: []string{"tcp://192.0.2.1", "tcp://192.0.2.2"},
DeviceID: device1,
Addresses: []string{"tcp://192.0.2.1", "tcp://192.0.2.2"},
AllowedNetworks: []string{},
},
device2: {
DeviceID: device2,
Addresses: []string{"tcp://192.0.2.3:6070", "tcp://[2001:db8::42]:4242"},
DeviceID: device2,
Addresses: []string{"tcp://192.0.2.3:6070", "tcp://[2001:db8::42]:4242"},
AllowedNetworks: []string{},
},
device3: {
DeviceID: device3,
Addresses: []string{"tcp://[2001:db8::44]:4444", "tcp://192.0.2.4:6090"},
DeviceID: device3,
Addresses: []string{"tcp://[2001:db8::44]:4444", "tcp://192.0.2.4:6090"},
AllowedNetworks: []string{},
},
device4: {
DeviceID: device4,
Name: name, // Set when auto created
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
DeviceID: device4,
Name: name, // Set when auto created
Addresses: []string{"dynamic"},
Compression: protocol.CompressMetadata,
AllowedNetworks: []string{},
},
}
+19 -5
View File
@@ -18,22 +18,36 @@ type DeviceConfiguration struct {
SkipIntroductionRemovals bool `xml:"skipIntroductionRemovals,attr" json:"skipIntroductionRemovals"`
IntroducedBy protocol.DeviceID `xml:"introducedBy,attr" json:"introducedBy"`
Paused bool `xml:"paused" json:"paused"`
AllowedNetworks []string `xml:"allowedNetwork,omitempty" json:"allowedNetworks"`
}
func NewDeviceConfiguration(id protocol.DeviceID, name string) DeviceConfiguration {
return DeviceConfiguration{
d := DeviceConfiguration{
DeviceID: id,
Name: name,
}
d.prepare()
return d
}
func (orig DeviceConfiguration) Copy() DeviceConfiguration {
c := orig
c.Addresses = make([]string, len(orig.Addresses))
copy(c.Addresses, orig.Addresses)
func (cfg DeviceConfiguration) Copy() DeviceConfiguration {
c := cfg
c.Addresses = make([]string, len(cfg.Addresses))
copy(c.Addresses, cfg.Addresses)
c.AllowedNetworks = make([]string, len(cfg.AllowedNetworks))
copy(c.AllowedNetworks, cfg.AllowedNetworks)
return c
}
func (cfg *DeviceConfiguration) prepare() {
if len(cfg.Addresses) == 0 || len(cfg.Addresses) == 1 && cfg.Addresses[0] == "" {
cfg.Addresses = []string{"dynamic"}
}
if len(cfg.AllowedNetworks) == 0 {
cfg.AllowedNetworks = []string{}
}
}
type DeviceConfigurationList []DeviceConfiguration
func (l DeviceConfigurationList) Less(a, b int) bool {
+66
View File
@@ -24,3 +24,69 @@ func TestFixupPort(t *testing.T) {
}
}
}
func TestAllowedNetworks(t *testing.T) {
cases := []struct {
host string
allowed []string
ok bool
}{
{
"192.168.0.1",
nil,
false,
},
{
"192.168.0.1",
[]string{},
false,
},
{
"fe80::1",
nil,
false,
},
{
"fe80::1",
[]string{},
false,
},
{
"192.168.0.1",
[]string{"fe80::/48", "192.168.0.0/24"},
true,
},
{
"fe80::1",
[]string{"192.168.0.0/24", "fe80::/48"},
true,
},
{
"192.168.0.1",
[]string{"192.168.1.0/24", "fe80::/48"},
false,
},
{
"fe80::1",
[]string{"fe82::/48", "192.168.1.0/24"},
false,
},
{
"192.168.0.1:4242",
[]string{"fe80::/48", "192.168.0.0/24"},
true,
},
{
"[fe80::1]:4242",
[]string{"192.168.0.0/24", "fe80::/48"},
true,
},
}
for _, tc := range cases {
res := IsAllowedNetwork(tc.host, tc.allowed)
if res != tc.ok {
t.Errorf("allowedNetwork(%q, %q) == %v, want %v", tc.host, tc.allowed, res, tc.ok)
}
}
}
+32
View File
@@ -371,6 +371,13 @@ func (s *Service) connect() {
continue
}
if len(deviceCfg.AllowedNetworks) > 0 {
if !IsAllowedNetwork(uri.Host, deviceCfg.AllowedNetworks) {
l.Debugln("Network for", uri, "is disallowed")
continue
}
}
dialerFactory, err := s.getDialerFactory(cfg, uri)
if err == errDisabled {
l.Debugln("Dialer for", uri, "is disabled")
@@ -641,3 +648,28 @@ func tlsTimedHandshake(tc *tls.Conn) error {
defer tc.SetDeadline(time.Time{})
return tc.Handshake()
}
// IsAllowedNetwork returns true if the given host (IP or resolvable
// hostname) is in the set of allowed networks (CIDR format only).
func IsAllowedNetwork(host string, allowed []string) bool {
if hostNoPort, _, err := net.SplitHostPort(host); err == nil {
host = hostNoPort
}
addr, err := net.ResolveIPAddr("ip", host)
if err != nil {
return false
}
for _, n := range allowed {
_, cidr, err := net.ParseCIDR(n)
if err != nil {
continue
}
if cidr.Contains(addr.IP) {
return true
}
}
return false
}
+1 -1
View File
@@ -303,7 +303,7 @@ func (s *FileSet) SetIndexID(device protocol.DeviceID, id protocol.IndexID) {
func (s *FileSet) MtimeFS() *fs.MtimeFS {
prefix := s.db.mtimesKey([]byte(s.folder))
kv := NewNamespacedKV(s.db, string(prefix))
return fs.NewMtimeFS(kv)
return fs.NewMtimeFS(fs.DefaultFilesystem, kv)
}
func (s *FileSet) ListDevices() []protocol.DeviceID {
+24 -3
View File
@@ -32,7 +32,7 @@ func (f *BasicFilesystem) Mkdir(name string, perm FileMode) error {
}
func (f *BasicFilesystem) Lstat(name string) (FileInfo, error) {
fi, err := os.Lstat(name)
fi, err := underlyingLstat(name)
if err != nil {
return nil, err
}
@@ -71,11 +71,32 @@ func (f *BasicFilesystem) DirNames(name string) ([]string, error) {
}
func (f *BasicFilesystem) Open(name string) (File, error) {
return os.Open(name)
fd, err := os.Open(name)
if err != nil {
return nil, err
}
return fsFile{fd}, err
}
func (f *BasicFilesystem) Create(name string) (File, error) {
return os.Create(name)
fd, err := os.Create(name)
if err != nil {
return nil, err
}
return fsFile{fd}, err
}
// fsFile implements the fs.File interface on top of an os.File
type fsFile struct {
*os.File
}
func (f fsFile) Stat() (FileInfo, error) {
info, err := f.File.Stat()
if err != nil {
return nil, err
}
return fsFileInfo{info}, nil
}
// fsFileInfo implements the fs.FileInfo interface on top of an os.FileInfo.
+14 -4
View File
@@ -7,8 +7,9 @@
package fs
import (
"errors"
"io"
"os"
"path/filepath"
"time"
)
@@ -37,6 +38,7 @@ type File interface {
io.WriterAt
io.Closer
Truncate(size int64) error
Stat() (FileInfo, error)
}
// The FileInfo interface is almost the same as os.FileInfo, but with the
@@ -57,12 +59,20 @@ type FileInfo interface {
// FileMode is similar to os.FileMode
type FileMode uint32
// ModePerm is the equivalent of os.ModePerm
const ModePerm = FileMode(os.ModePerm)
// DefaultFilesystem is the fallback to use when nothing explicitly has
// been passed.
var DefaultFilesystem Filesystem = new(BasicFilesystem)
var DefaultFilesystem Filesystem = NewBasicFilesystem()
// SkipDir is used as a return value from WalkFuncs to indicate that
// the directory named in the call is to be skipped. It is not returned
// as an error by any function.
var errSkipDir = errors.New("skip this directory")
var SkipDir = errSkipDir // silences the lint warning...
var SkipDir = filepath.SkipDir
// IsExist is the equivalent of os.IsExist
var IsExist = os.IsExist
// IsNotExist is the equivalent of os.IsNotExist
var IsNotExist = os.IsNotExist
+29
View File
@@ -0,0 +1,29 @@
// Copyright (C) 2015 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
// +build linux android
package fs
import (
"os"
"syscall"
"time"
)
// Lstat is like os.Lstat, except lobotomized for Android. See
// https://forum.syncthing.net/t/2395
func underlyingLstat(name string) (fi os.FileInfo, err error) {
for i := 0; i < 10; i++ { // We have to draw the line somewhere
fi, err = os.Lstat(name)
if err, ok := err.(*os.PathError); ok && err.Err == syscall.EINTR {
time.Sleep(time.Duration(i+1) * time.Millisecond)
continue
}
return
}
return
}
+15
View File
@@ -0,0 +1,15 @@
// Copyright (C) 2015 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
// +build !linux,!android
package fs
import "os"
func underlyingLstat(name string) (fi os.FileInfo, err error) {
return os.Lstat(name)
}
+7 -9
View File
@@ -27,12 +27,14 @@ var osChtimes = os.Chtimes
// of what shenanigans the underlying filesystem gets up to. A nil MtimeFS
// just does the underlying operations with no additions.
type MtimeFS struct {
Filesystem
db database
}
func NewMtimeFS(db database) *MtimeFS {
func NewMtimeFS(underlying Filesystem, db database) *MtimeFS {
return &MtimeFS{
db: db,
Filesystem: underlying,
db: db,
}
}
@@ -56,12 +58,8 @@ func (f *MtimeFS) Chtimes(name string, atime, mtime time.Time) error {
return nil
}
func (f *MtimeFS) Lstat(name string) (os.FileInfo, error) {
if f == nil {
return osutil.Lstat(name)
}
info, err := osutil.Lstat(name)
func (f *MtimeFS) Lstat(name string) (FileInfo, error) {
info, err := f.Filesystem.Lstat(name)
if err != nil {
return nil, err
}
@@ -113,7 +111,7 @@ func (f *MtimeFS) load(name string) (real, virtual time.Time) {
// The mtimeFileInfo is an os.FileInfo that lies about the ModTime().
type mtimeFileInfo struct {
os.FileInfo
FileInfo
mtime time.Time
}
+1 -1
View File
@@ -25,7 +25,7 @@ func TestMtimeFS(t *testing.T) {
// a random time with nanosecond precision
testTime := time.Unix(1234567890, 123456789)
mtimefs := NewMtimeFS(make(mapStore))
mtimefs := NewMtimeFS(DefaultFilesystem, make(mapStore))
// Do one Chtimes call that will go through to the normal filesystem
osChtimes = os.Chtimes
+30 -14
View File
@@ -119,6 +119,7 @@ var (
errNotRelative = errors.New("not a relative path")
errFolderPaused = errors.New("folder is paused")
errFolderMissing = errors.New("no such folder")
errNetworkNotAllowed = errors.New("network not allowed")
)
// NewModel creates and starts a new model. The model starts in read-only mode,
@@ -231,8 +232,17 @@ func (m *Model) startFolderLocked(folder string) config.FolderType {
// if these things don't work, we still want to start the folder and
// it'll show up as errored later.
// Directory permission bits. Will be filtered down to something
// sane by umask on Unixes.
permBits := os.FileMode(0777)
if runtime.GOOS == "windows" {
// Windows has no umask so we must chose a safer set of bits to
// begin with.
permBits = 0700
}
if _, err := os.Stat(cfg.Path()); os.IsNotExist(err) {
if err := osutil.MkdirAll(cfg.Path(), 0700); err != nil {
if err := osutil.MkdirAll(cfg.Path(), permBits); err != nil {
l.Warnln("Creating folder:", err)
}
}
@@ -1312,21 +1322,27 @@ func (m *Model) OnHello(remoteID protocol.DeviceID, addr net.Addr, hello protoco
return errDeviceIgnored
}
if cfg, ok := m.cfg.Device(remoteID); ok {
// The device exists
if cfg.Paused {
return errDevicePaused
}
return nil
cfg, ok := m.cfg.Device(remoteID)
if !ok {
events.Default.Log(events.DeviceRejected, map[string]string{
"name": hello.DeviceName,
"device": remoteID.String(),
"address": addr.String(),
})
return errDeviceUnknown
}
events.Default.Log(events.DeviceRejected, map[string]string{
"name": hello.DeviceName,
"device": remoteID.String(),
"address": addr.String(),
})
if cfg.Paused {
return errDevicePaused
}
return errDeviceUnknown
if len(cfg.AllowedNetworks) > 0 {
if !connections.IsAllowedNetwork(addr.String(), cfg.AllowedNetworks) {
return errNetworkNotAllowed
}
}
return nil
}
// GetHello is called when we are about to connect to some remote device.
@@ -1811,7 +1827,7 @@ func (m *Model) internalScanFolderSubdirs(folder string, subDirs []string) error
BlockSize: protocol.BlockSize,
TempLifetime: time.Duration(m.cfg.Options().KeepTemporariesH) * time.Hour,
CurrentFiler: cFiler{m, folder},
Lstater: mtimefs,
Filesystem: mtimefs,
IgnorePerms: folderCfg.IgnorePerms,
AutoNormalize: folderCfg.AutoNormalize,
Hashers: m.numHashers(folder),
+10 -4
View File
@@ -968,6 +968,12 @@ func TestIgnores(t *testing.T) {
ignores = append(ignores, "pox")
if runtime.GOOS == "darwin" {
// Mac has seconds-only timestamp precision, which tricks the ignore
// system into thinking the file has not changed. Work around it in
// an ugly way...
time.Sleep(time.Second)
}
err = m.SetIgnores("default", ignores)
if err != nil {
t.Error(err)
@@ -978,14 +984,14 @@ func TestIgnores(t *testing.T) {
t.Error(err)
}
if arrEqual(expected, ignores2) {
t.Errorf("Incorrect ignores: %v == %v", ignores2, expected)
}
if !arrEqual(ignores, ignores2) {
t.Errorf("Incorrect ignores: %v != %v", ignores2, ignores)
}
if runtime.GOOS == "darwin" {
// see above
time.Sleep(time.Second)
}
err = m.SetIgnores("default", expected)
if err != nil {
t.Error(err)
+5 -5
View File
@@ -627,7 +627,7 @@ func (f *sendReceiveFolder) handleDir(file protocol.FileInfo) {
// There is already something under that name, but it's a file/link.
// Most likely a file/link is getting replaced with a directory.
// Remove the file/link and fall through to directory creation.
case err == nil && (!info.IsDir() || info.Mode()&os.ModeSymlink != 0):
case err == nil && (!info.IsDir() || info.IsSymlink()):
err = osutil.InWritableDir(os.Remove, realName)
if err != nil {
l.Infof("Puller (folder %q, dir %q): %v", f.folderID, file.Name, err)
@@ -655,7 +655,7 @@ func (f *sendReceiveFolder) handleDir(file protocol.FileInfo) {
// Mask for the bits we want to preserve and add them in to the
// directories permissions.
return os.Chmod(path, mode|(info.Mode()&retainBits))
return os.Chmod(path, mode|(os.FileMode(info.Mode())&retainBits))
}
if err = osutil.InWritableDir(mkdir, realName); err == nil {
@@ -678,7 +678,7 @@ func (f *sendReceiveFolder) handleDir(file protocol.FileInfo) {
// It's OK to change mode bits on stuff within non-writable directories.
if f.ignorePermissions(file) {
f.dbUpdates <- dbUpdateJob{file, dbUpdateHandleDir}
} else if err := os.Chmod(realName, mode|(info.Mode()&retainBits)); err == nil {
} else if err := os.Chmod(realName, mode|(os.FileMode(info.Mode())&retainBits)); err == nil {
f.dbUpdates <- dbUpdateJob{file, dbUpdateHandleDir}
} else {
l.Infof("Puller (folder %q, dir %q): %v", f.folderID, file.Name, err)
@@ -1077,7 +1077,7 @@ func (f *sendReceiveFolder) handleFile(file protocol.FileInfo, copyChan chan<- c
// Check for an old temporary file which might have some blocks we could
// reuse.
tempBlocks, err := scanner.HashFile(tempName, protocol.BlockSize, nil, false)
tempBlocks, err := scanner.HashFile(fs.DefaultFilesystem, tempName, protocol.BlockSize, nil, false)
if err == nil {
// Check for any reusable blocks in the temp file
tempCopyBlocks, _ := scanner.BlockDiff(tempBlocks, file.Blocks)
@@ -1431,7 +1431,7 @@ func (f *sendReceiveFolder) performFinish(state *sharedPullerState) error {
// handle that.
switch {
case stat.IsDir() || stat.Mode()&os.ModeSymlink != 0:
case stat.IsDir() || stat.IsSymlink():
// It's a directory or a symlink. These are not versioned or
// archived for conflicts, only removed (which of course fails for
// non-empty directories).
+2 -2
View File
@@ -84,7 +84,7 @@ func setUpSendReceiveFolder(model *Model) sendReceiveFolder {
model: model,
},
mtimeFS: fs.NewMtimeFS(db.NewNamespacedKV(model.db, "mtime")),
mtimeFS: fs.NewMtimeFS(fs.DefaultFilesystem, db.NewNamespacedKV(model.db, "mtime")),
dir: "testdata",
queue: newJobQueue(),
errors: make(map[string]string),
@@ -238,7 +238,7 @@ func TestCopierFinder(t *testing.T) {
}
// Verify that the fetched blocks have actually been written to the temp file
blks, err := scanner.HashFile(tempFile, protocol.BlockSize, nil, false)
blks, err := scanner.HashFile(fs.DefaultFilesystem, tempFile, protocol.BlockSize, nil, false)
if err != nil {
t.Log(err)
}
+31 -4
View File
@@ -57,6 +57,9 @@ var (
errUnknownMessage = errors.New("unknown message")
errInvalidFilename = errors.New("filename is invalid")
errUncleanFilename = errors.New("filename not in canonical format")
errDeletedHasBlocks = errors.New("deleted file with non-empty block list")
errDirectoryHasBlocks = errors.New("directory with non-empty block list")
errFileHasNoBlocks = errors.New("file with empty block list")
)
type Model interface {
@@ -308,7 +311,7 @@ func (c *rawConnection) readerLoop() (err error) {
if state != stateReady {
return fmt.Errorf("protocol error: index message in state %d", state)
}
if err := checkFilenames(msg.Files); err != nil {
if err := checkIndexConsistency(msg.Files); err != nil {
return fmt.Errorf("protocol error: index: %v", err)
}
c.handleIndex(*msg)
@@ -319,7 +322,7 @@ func (c *rawConnection) readerLoop() (err error) {
if state != stateReady {
return fmt.Errorf("protocol error: index update message in state %d", state)
}
if err := checkFilenames(msg.Files); err != nil {
if err := checkIndexConsistency(msg.Files); err != nil {
return fmt.Errorf("protocol error: index update: %v", err)
}
c.handleIndexUpdate(*msg)
@@ -466,15 +469,39 @@ func (c *rawConnection) handleIndexUpdate(im IndexUpdate) {
c.receiver.IndexUpdate(c.id, im.Folder, im.Files)
}
func checkFilenames(fs []FileInfo) error {
// checkIndexConsistency verifies a number of invariants on FileInfos received in
// index messages.
func checkIndexConsistency(fs []FileInfo) error {
for _, f := range fs {
if err := checkFilename(f.Name); err != nil {
if err := checkFileInfoConsistency(f); err != nil {
return fmt.Errorf("%q: %v", f.Name, err)
}
}
return nil
}
// checkFileInfoConsistency verifies a number of invariants on the given FileInfo
func checkFileInfoConsistency(f FileInfo) error {
if err := checkFilename(f.Name); err != nil {
return err
}
switch {
case f.Deleted && len(f.Blocks) != 0:
// Deleted files should have no blocks
return errDeletedHasBlocks
case f.Type == FileInfoTypeDirectory && len(f.Blocks) != 0:
// Directories should have no blocks
return errDirectoryHasBlocks
case !f.Deleted && !f.Invalid && f.Type == FileInfoTypeFile && len(f.Blocks) == 0:
// Non-deleted, non-invalid files should have at least one block
return errFileHasNoBlocks
}
return nil
}
// checkFilename verifies that the given filename is valid according to the
// spec on what's allowed over the wire. A filename failing this test is
// grounds for disconnecting the device.
+54
View File
@@ -346,3 +346,57 @@ func TestCheckFilename(t *testing.T) {
}
}
}
func TestCheckConsistency(t *testing.T) {
cases := []struct {
fi FileInfo
ok bool
}{
{
// valid
fi: FileInfo{
Name: "foo",
Type: FileInfoTypeFile,
Blocks: []BlockInfo{{Size: 1234, Offset: 0, Hash: []byte{1, 2, 3, 4}}},
},
ok: true,
},
{
// deleted with blocks
fi: FileInfo{
Name: "foo",
Deleted: true,
Type: FileInfoTypeFile,
Blocks: []BlockInfo{{Size: 1234, Offset: 0, Hash: []byte{1, 2, 3, 4}}},
},
ok: false,
},
{
// no blocks
fi: FileInfo{
Name: "foo",
Type: FileInfoTypeFile,
},
ok: false,
},
{
// directory with blocks
fi: FileInfo{
Name: "foo",
Type: FileInfoTypeDirectory,
Blocks: []BlockInfo{{Size: 1234, Offset: 0, Hash: []byte{1, 2, 3, 4}}},
},
ok: false,
},
}
for _, tc := range cases {
err := checkFileInfoConsistency(tc.fi)
if tc.ok && err != nil {
t.Errorf("Unexpected error %v (want nil) for %v", err, tc.fi)
}
if !tc.ok && err == nil {
t.Errorf("Unexpected nil error for %v", tc.fi)
}
}
}
+60 -34
View File
@@ -8,41 +8,16 @@ package scanner
import (
"errors"
"os"
"path/filepath"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/sync"
)
// The parallel hasher reads FileInfo structures from the inbox, hashes the
// file to populate the Blocks element and sends it to the outbox. A number of
// workers are used in parallel. The outbox will become closed when the inbox
// is closed and all items handled.
func newParallelHasher(dir string, blockSize, workers int, outbox, inbox chan protocol.FileInfo, counter Counter, done, cancel chan struct{}, useWeakHashes bool) {
wg := sync.NewWaitGroup()
wg.Add(workers)
for i := 0; i < workers; i++ {
go func() {
hashFiles(dir, blockSize, outbox, inbox, counter, cancel, useWeakHashes)
wg.Done()
}()
}
go func() {
wg.Wait()
if done != nil {
close(done)
}
close(outbox)
}()
}
// HashFile hashes the files and returns a list of blocks representing the file.
func HashFile(path string, blockSize int, counter Counter, useWeakHashes bool) ([]protocol.BlockInfo, error) {
fd, err := os.Open(path)
func HashFile(fs fs.Filesystem, path string, blockSize int, counter Counter, useWeakHashes bool) ([]protocol.BlockInfo, error) {
fd, err := fs.Open(path)
if err != nil {
l.Debugln("open:", err)
return nil, err
@@ -82,10 +57,53 @@ func HashFile(path string, blockSize int, counter Counter, useWeakHashes bool) (
return blocks, nil
}
func hashFiles(dir string, blockSize int, outbox, inbox chan protocol.FileInfo, counter Counter, cancel chan struct{}, useWeakHashes bool) {
// The parallel hasher reads FileInfo structures from the inbox, hashes the
// file to populate the Blocks element and sends it to the outbox. A number of
// workers are used in parallel. The outbox will become closed when the inbox
// is closed and all items handled.
type parallelHasher struct {
fs fs.Filesystem
dir string
blockSize int
workers int
outbox chan<- protocol.FileInfo
inbox <-chan protocol.FileInfo
counter Counter
done chan<- struct{}
cancel <-chan struct{}
useWeakHashes bool
wg sync.WaitGroup
}
func newParallelHasher(fs fs.Filesystem, dir string, blockSize, workers int, outbox chan<- protocol.FileInfo, inbox <-chan protocol.FileInfo, counter Counter, done chan<- struct{}, cancel <-chan struct{}, useWeakHashes bool) {
ph := &parallelHasher{
fs: fs,
dir: dir,
blockSize: blockSize,
workers: workers,
outbox: outbox,
inbox: inbox,
counter: counter,
done: done,
cancel: cancel,
useWeakHashes: useWeakHashes,
wg: sync.NewWaitGroup(),
}
for i := 0; i < workers; i++ {
ph.wg.Add(1)
go ph.hashFiles()
}
go ph.closeWhenDone()
}
func (ph *parallelHasher) hashFiles() {
defer ph.wg.Done()
for {
select {
case f, ok := <-inbox:
case f, ok := <-ph.inbox:
if !ok {
return
}
@@ -94,7 +112,7 @@ func hashFiles(dir string, blockSize int, outbox, inbox chan protocol.FileInfo,
panic("Bug. Asked to hash a directory or a deleted file.")
}
blocks, err := HashFile(filepath.Join(dir, f.Name), blockSize, counter, useWeakHashes)
blocks, err := HashFile(ph.fs, filepath.Join(ph.dir, f.Name), ph.blockSize, ph.counter, ph.useWeakHashes)
if err != nil {
l.Debugln("hash error:", f.Name, err)
continue
@@ -112,13 +130,21 @@ func hashFiles(dir string, blockSize int, outbox, inbox chan protocol.FileInfo,
}
select {
case outbox <- f:
case <-cancel:
case ph.outbox <- f:
case <-ph.cancel:
return
}
case <-cancel:
case <-ph.cancel:
return
}
}
}
func (ph *parallelHasher) closeWhenDone() {
ph.wg.Wait()
if ph.done != nil {
close(ph.done)
}
close(ph.outbox)
}
+30 -42
View File
@@ -8,7 +8,6 @@ package scanner
import (
"errors"
"os"
"path/filepath"
"runtime"
"sync/atomic"
@@ -17,24 +16,25 @@ import (
"github.com/rcrowley/go-metrics"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/ignore"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/protocol"
"golang.org/x/text/unicode/norm"
)
var maskModePerm os.FileMode
var maskModePerm fs.FileMode
func init() {
if runtime.GOOS == "windows" {
// There is no user/group/others in Windows' read-only
// attribute, and all "w" bits are set in os.FileInfo
// attribute, and all "w" bits are set in fs.FileMode
// if the file is not read-only. Do not send these
// group/others-writable bits to other devices in order to
// avoid unexpected world-writable files on other platforms.
maskModePerm = os.ModePerm & 0755
maskModePerm = fs.ModePerm & 0755
} else {
maskModePerm = os.ModePerm
maskModePerm = fs.ModePerm
}
}
@@ -53,8 +53,8 @@ type Config struct {
TempLifetime time.Duration
// If CurrentFiler is not nil, it is queried for the current file before rescanning.
CurrentFiler CurrentFiler
// The Lstater provides reliable mtimes on top of the regular filesystem.
Lstater Lstater
// The Filesystem provides an abstraction on top of the actual filesystem.
Filesystem fs.Filesystem
// If IgnorePerms is true, changes to permission bits will not be
// detected. Scanned files will get zero permission bits and the
// NoPermissionBits flag set.
@@ -80,18 +80,14 @@ type CurrentFiler interface {
CurrentFile(name string) (protocol.FileInfo, bool)
}
type Lstater interface {
Lstat(name string) (os.FileInfo, error)
}
func Walk(cfg Config) (chan protocol.FileInfo, error) {
w := walker{cfg}
if w.CurrentFiler == nil {
w.CurrentFiler = noCurrentFiler{}
}
if w.Lstater == nil {
w.Lstater = defaultLstater{}
if w.Filesystem == nil {
w.Filesystem = fs.DefaultFilesystem
}
return w.walk()
@@ -118,10 +114,10 @@ func (w *walker) walk() (chan protocol.FileInfo, error) {
go func() {
hashFiles := w.walkAndHashFiles(toHashChan, finishedChan)
if len(w.Subs) == 0 {
filepath.Walk(w.Dir, hashFiles)
w.Filesystem.Walk(w.Dir, hashFiles)
} else {
for _, sub := range w.Subs {
filepath.Walk(filepath.Join(w.Dir, sub), hashFiles)
w.Filesystem.Walk(filepath.Join(w.Dir, sub), hashFiles)
}
}
close(toHashChan)
@@ -130,7 +126,7 @@ func (w *walker) walk() (chan protocol.FileInfo, error) {
// We're not required to emit scan progress events, just kick off hashers,
// and feed inputs directly from the walker.
if w.ProgressTickIntervalS < 0 {
newParallelHasher(w.Dir, w.BlockSize, w.Hashers, finishedChan, toHashChan, nil, nil, w.Cancel, w.UseWeakHashes)
newParallelHasher(w.Filesystem, w.Dir, w.BlockSize, w.Hashers, finishedChan, toHashChan, nil, nil, w.Cancel, w.UseWeakHashes)
return finishedChan, nil
}
@@ -161,7 +157,7 @@ func (w *walker) walk() (chan protocol.FileInfo, error) {
done := make(chan struct{})
progress := newByteCounter()
newParallelHasher(w.Dir, w.BlockSize, w.Hashers, finishedChan, realToHashChan, progress, done, w.Cancel, w.UseWeakHashes)
newParallelHasher(w.Filesystem, w.Dir, w.BlockSize, w.Hashers, finishedChan, realToHashChan, progress, done, w.Cancel, w.UseWeakHashes)
// A routine which actually emits the FolderScanProgress events
// every w.ProgressTicker ticks, until the hasher routines terminate.
@@ -206,15 +202,15 @@ func (w *walker) walk() (chan protocol.FileInfo, error) {
return finishedChan, nil
}
func (w *walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath.WalkFunc {
func (w *walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) fs.WalkFunc {
now := time.Now()
return func(absPath string, info os.FileInfo, err error) error {
return func(absPath string, info fs.FileInfo, err error) error {
// Return value used when we are returning early and don't want to
// process the item. For directories, this means do-not-descend.
var skip error // nil
// info nil when error is not nil
if info != nil && info.IsDir() {
skip = filepath.SkipDir
skip = fs.SkipDir
}
if err != nil {
@@ -232,7 +228,7 @@ func (w *walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath.
return nil
}
info, err = w.Lstater.Lstat(absPath)
info, err = w.Filesystem.Lstat(absPath)
// An error here would be weird as we've already gotten to this point, but act on it nonetheless
if err != nil {
return skip
@@ -240,8 +236,8 @@ func (w *walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath.
if ignore.IsTemporary(relPath) {
l.Debugln("temporary:", relPath)
if info.Mode().IsRegular() && info.ModTime().Add(w.TempLifetime).Before(now) {
os.Remove(absPath)
if info.IsRegular() && info.ModTime().Add(w.TempLifetime).Before(now) {
w.Filesystem.Remove(absPath)
l.Debugln("removing temporary:", relPath, info.ModTime())
}
return nil
@@ -268,20 +264,20 @@ func (w *walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath.
}
switch {
case info.Mode()&os.ModeSymlink == os.ModeSymlink:
case info.IsSymlink():
if err := w.walkSymlink(absPath, relPath, dchan); err != nil {
return err
}
if info.IsDir() {
// under no circumstances shall we descend into a symlink
return filepath.SkipDir
return fs.SkipDir
}
return nil
case info.Mode().IsDir():
case info.IsDir():
err = w.walkDir(relPath, info, dchan)
case info.Mode().IsRegular():
case info.IsRegular():
err = w.walkRegular(relPath, info, fchan)
}
@@ -289,7 +285,7 @@ func (w *walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath.
}
}
func (w *walker) walkRegular(relPath string, info os.FileInfo, fchan chan protocol.FileInfo) error {
func (w *walker) walkRegular(relPath string, info fs.FileInfo, fchan chan protocol.FileInfo) error {
curMode := uint32(info.Mode())
if runtime.GOOS == "windows" && osutil.IsWindowsExecutable(relPath) {
curMode |= 0111
@@ -312,7 +308,7 @@ func (w *walker) walkRegular(relPath string, info os.FileInfo, fchan chan protoc
}
if ok {
l.Debugln("rescan:", cf, info.ModTime().Unix(), info.Mode()&os.ModePerm)
l.Debugln("rescan:", cf, info.ModTime().Unix(), info.Mode()&fs.ModePerm)
}
f := protocol.FileInfo{
@@ -337,7 +333,7 @@ func (w *walker) walkRegular(relPath string, info os.FileInfo, fchan chan protoc
return nil
}
func (w *walker) walkDir(relPath string, info os.FileInfo, dchan chan protocol.FileInfo) error {
func (w *walker) walkDir(relPath string, info fs.FileInfo, dchan chan protocol.FileInfo) error {
// A directory is "unchanged", if it
// - exists
// - has the same permissions as previously, unless we are ignoring permissions
@@ -386,7 +382,7 @@ func (w *walker) walkSymlink(absPath, relPath string, dchan chan protocol.FileIn
// checking that their existing blocks match with the blocks in
// the index.
target, err := os.Readlink(absPath)
target, err := w.Filesystem.ReadSymlink(absPath)
if err != nil {
l.Debugln("readlink error:", absPath, err)
return nil
@@ -448,9 +444,9 @@ func (w *walker) normalizePath(absPath, relPath string) (normPath string, skip b
// We will attempt to normalize it.
normalizedPath := filepath.Join(w.Dir, normPath)
if _, err := w.Lstater.Lstat(normalizedPath); os.IsNotExist(err) {
if _, err := w.Filesystem.Lstat(normalizedPath); fs.IsNotExist(err) {
// Nothing exists with the normalized filename. Good.
if err = os.Rename(absPath, normalizedPath); err != nil {
if err = w.Filesystem.Rename(absPath, normalizedPath); err != nil {
l.Infof(`Error normalizing UTF8 encoding of file "%s": %v`, relPath, err)
return "", true
}
@@ -467,7 +463,7 @@ func (w *walker) normalizePath(absPath, relPath string) (normPath string, skip b
}
func (w *walker) checkDir() error {
if info, err := w.Lstater.Lstat(w.Dir); err != nil {
if info, err := w.Filesystem.Lstat(w.Dir); err != nil {
return err
} else if !info.IsDir() {
return errors.New(w.Dir + ": not a directory")
@@ -541,11 +537,3 @@ type noCurrentFiler struct{}
func (noCurrentFiler) CurrentFile(name string) (protocol.FileInfo, bool) {
return protocol.FileInfo{}, false
}
// A no-op Lstater
type defaultLstater struct{}
func (defaultLstater) Lstat(name string) (os.FileInfo, error) {
return osutil.Lstat(name)
}
+2 -1
View File
@@ -20,6 +20,7 @@ import (
"testing"
"github.com/d4l3k/messagediff"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/ignore"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/protocol"
@@ -433,7 +434,7 @@ func BenchmarkHashFile(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := HashFile(testdataName, protocol.BlockSize, nil, true); err != nil {
if _, err := HashFile(fs.DefaultFilesystem, testdataName, protocol.BlockSize, nil, true); err != nil {
b.Fatal(err)
}
}
+19 -7
View File
@@ -19,6 +19,12 @@ import (
"github.com/sasha-s/go-deadlock"
)
type clock interface {
Now() time.Time
}
var defaultClock clock = (*standardClock)(nil)
type Mutex interface {
Lock()
Unlock()
@@ -80,7 +86,7 @@ func (h holder) String() string {
if h.at == "" {
return "not held"
}
return fmt.Sprintf("at %s goid: %d for %s", h.at, h.goid, time.Since(h.time))
return fmt.Sprintf("at %s goid: %d for %s", h.at, h.goid, defaultClock.Now().Sub(h.time))
}
type loggedMutex struct {
@@ -95,7 +101,7 @@ func (m *loggedMutex) Lock() {
func (m *loggedMutex) Unlock() {
currentHolder := m.holder.Load().(holder)
duration := time.Since(currentHolder.time)
duration := defaultClock.Now().Sub(currentHolder.time)
if duration >= threshold {
l.Debugf("Mutex held for %v. Locked at %s unlocked at %s", duration, currentHolder.at, getHolder().at)
}
@@ -119,7 +125,7 @@ type loggedRWMutex struct {
}
func (m *loggedRWMutex) Lock() {
start := time.Now()
start := defaultClock.Now()
atomic.StoreInt32(&m.logUnlockers, 1)
m.RWMutex.Lock()
@@ -147,7 +153,7 @@ func (m *loggedRWMutex) Lock() {
func (m *loggedRWMutex) Unlock() {
currentHolder := m.holder.Load().(holder)
duration := time.Since(currentHolder.time)
duration := defaultClock.Now().Sub(currentHolder.time)
if duration >= threshold {
l.Debugf("RWMutex held for %v. Locked at %s unlocked at %s", duration, currentHolder.at, getHolder().at)
}
@@ -199,9 +205,9 @@ type loggedWaitGroup struct {
}
func (wg *loggedWaitGroup) Wait() {
start := time.Now()
start := defaultClock.Now()
wg.WaitGroup.Wait()
duration := time.Since(start)
duration := defaultClock.Now().Sub(start)
if duration >= threshold {
l.Debugf("WaitGroup took %v at %s", duration, getHolder())
}
@@ -213,7 +219,7 @@ func getHolder() holder {
return holder{
at: fmt.Sprintf("%s:%d", file, line),
goid: goid(),
time: time.Now(),
time: defaultClock.Now(),
}
}
@@ -294,3 +300,9 @@ func (w *TimeoutCondWaiter) Wait() bool {
func (w *TimeoutCondWaiter) Stop() {
w.timer.Stop()
}
type standardClock struct{}
func (*standardClock) Now() time.Time {
return time.Now()
}
+64 -39
View File
@@ -21,23 +21,6 @@ const (
longWait = 125 * time.Millisecond
)
var skipTimingTests = false
func init() {
// Check a few times that a short sleep does not in fact overrun the log
// threshold. If it does, the timer accuracy is crap or the host is
// overloaded and we can't reliably run the tests in here. In the normal
// case this takes just 25*5 = 125 ms.
for i := 0; i < 25; i++ {
t0 := time.Now()
time.Sleep(shortWait)
if time.Since(t0) > logThreshold {
skipTimingTests = true
return
}
}
}
func TestTypes(t *testing.T) {
debug = false
l.SetDebug("sync", false)
@@ -74,10 +57,10 @@ func TestTypes(t *testing.T) {
}
func TestMutex(t *testing.T) {
if skipTimingTests {
t.Skip("insufficient timer accuracy")
return
}
oldClock := defaultClock
clock := newTestClock()
defaultClock = clock
defer func() { defaultClock = oldClock }()
debug = true
l.SetDebug("sync", true)
@@ -94,7 +77,7 @@ func TestMutex(t *testing.T) {
mut := NewMutex()
mut.Lock()
time.Sleep(shortWait)
clock.wind(shortWait)
mut.Unlock()
if len(messages) > 0 {
@@ -102,7 +85,7 @@ func TestMutex(t *testing.T) {
}
mut.Lock()
time.Sleep(longWait)
clock.wind(longWait)
mut.Unlock()
if len(messages) != 1 {
@@ -114,10 +97,10 @@ func TestMutex(t *testing.T) {
}
func TestRWMutex(t *testing.T) {
if skipTimingTests {
t.Skip("insufficient timer accuracy")
return
}
oldClock := defaultClock
clock := newTestClock()
defaultClock = clock
defer func() { defaultClock = oldClock }()
debug = true
l.SetDebug("sync", true)
@@ -134,7 +117,7 @@ func TestRWMutex(t *testing.T) {
mut := NewRWMutex()
mut.Lock()
time.Sleep(shortWait)
clock.wind(shortWait)
mut.Unlock()
if len(messages) > 0 {
@@ -142,7 +125,7 @@ func TestRWMutex(t *testing.T) {
}
mut.Lock()
time.Sleep(longWait)
clock.wind(longWait)
mut.Unlock()
if len(messages) != 1 {
@@ -150,14 +133,21 @@ func TestRWMutex(t *testing.T) {
}
// Testing rlocker logging
wait := make(chan struct{})
locking := make(chan struct{})
mut.RLock()
go func() {
time.Sleep(longWait)
mut.RUnlock()
close(locking)
mut.Lock()
close(wait)
}()
mut.Lock()
_ = 1 // skip empty critical section check
<-locking
clock.wind(longWait)
mut.RUnlock()
<-wait
mut.Unlock()
if len(messages) != 2 {
@@ -181,10 +171,10 @@ func TestRWMutex(t *testing.T) {
}
func TestWaitGroup(t *testing.T) {
if skipTimingTests {
t.Skip("insufficient timer accuracy")
return
}
oldClock := defaultClock
clock := newTestClock()
defaultClock = clock
defer func() { defaultClock = oldClock }()
debug = true
l.SetDebug("sync", true)
@@ -201,10 +191,15 @@ func TestWaitGroup(t *testing.T) {
wg := NewWaitGroup()
wg.Add(1)
waiting := make(chan struct{})
go func() {
time.Sleep(shortWait)
<-waiting
clock.wind(shortWait)
wg.Done()
}()
close(waiting)
wg.Wait()
if len(messages) > 0 {
@@ -212,11 +207,16 @@ func TestWaitGroup(t *testing.T) {
}
wg = NewWaitGroup()
waiting = make(chan struct{})
wg.Add(1)
go func() {
time.Sleep(longWait)
<-waiting
clock.wind(longWait)
wg.Done()
}()
close(waiting)
wg.Wait()
if len(messages) != 1 {
@@ -323,3 +323,28 @@ func runLocks(t *testing.T, iterations int, c *TimeoutCond, d time.Duration) (su
}
return
}
type testClock struct {
time time.Time
mut sync.Mutex
}
func newTestClock() *testClock {
return &testClock{
time: time.Now(),
}
}
func (t *testClock) Now() time.Time {
t.mut.Lock()
now := t.time
t.time = t.time.Add(time.Nanosecond)
t.mut.Unlock()
return now
}
func (t *testClock) wind(d time.Duration) {
t.mut.Lock()
t.time = t.time.Add(d)
t.mut.Unlock()
}
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "STDISCOSRV" "1" "March 13, 2017" "v0.14" "Syncthing"
.TH "STDISCOSRV" "1" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
stdiscosrv \- Syncthing Discovery Server
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "STRELAYSRV" "1" "March 13, 2017" "v0.14" "Syncthing"
.TH "STRELAYSRV" "1" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
strelaysrv \- Syncthing Relay Server
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-BEP" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-BEP" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-bep \- Block Exchange Protocol v1
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-CONFIG" "5" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-CONFIG" "5" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-config \- Syncthing Configuration
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-DEVICE-IDS" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-DEVICE-IDS" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-device-ids \- Understanding Device IDs
.
+177 -10
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-EVENT-API" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-EVENT-API" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-event-api \- Event API
.
@@ -35,13 +35,17 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
Syncthing provides a simple long polling interface for exposing events from the
core utility towards a GUI.
.sp
To receive events, perform a HTTP GET of \fB/rest/events?since=<lastSeenID>\fP,
where \fB<lastSeenID>\fP is the ID of the last event you\(aqve already seen or zero.
Syncthing returns a JSON encoded array of event objects, starting at the event
just after the one with the last seen ID. There is a limit to the number of
events buffered, so if the rate of events is high or the time between polling
calls is long some events might be missed. This can be detected by noting a
discontinuity in the event IDs.
To receive events, perform a HTTP GET of \fB/rest/events\fP or
\fB/rest/events/disk\fP\&. The latter returns only local\-change\-detected and
local\-change\-detected events, the former all other events.
.sp
The optional parameter \fBsince=<lastSeenID>\fP sets the ID of the last event
you\(aqve already seen. Syncthing returns a JSON encoded array of event objects,
starting at the event just after the one with this last seen ID. The default
value is 0, which returns all events. There is a limit to the number of events
buffered, so if the rate of events is high or the time between polling calls is
long some events might be missed. This can be detected by noting a discontinuity
in the event IDs.
.sp
If no new events are produced since \fB<lastSeenID>\fP, the HTTP call blocks and
waits for new events to happen before returning. By default it times out after
@@ -449,6 +453,32 @@ have, or have but do not share with the device in question.
.fi
.UNINDENT
.UNINDENT
.SS Folder Scan Progress
.sp
Emitted in regular intervals (folder setting ProgressIntervalS, 2s by default)
during scans giving the amount of bytes already scanned and to be scanned in
total , as well as the current scanning rates in bytes per second.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"data" : {
"total" : 1,
"rate" : 0,
"current" : 0,
"folder" : "bd7q3\-zskm5"
},
"globalID" : 29,
"type" : "FolderScanProgress",
"time" : "2017\-03\-06T15:00:58.072004209+01:00",
"id" : 29
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS FolderSummary
.sp
The FolderSummary event is emitted when folder contents have changed
@@ -569,11 +599,69 @@ The \fBaction\fP field is either \fBupdate\fP (contents changed), \fBmetadata\fP
.sp
New in version 0.11.10: The \fBmetadata\fP action.
.SS Listen Addresses Changed
.sp
This event is emitted when a listen address changes.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"type" : "ListenAddressesChanged",
"id" : 70,
"time" : "2017\-03\-06T15:01:24.88340663+01:00",
"globalID" : 70,
"data" : {
"address" : {
"Fragment" : "",
"RawQuery" : "",
"Scheme" : "dynamic+https",
"Path" : "/endpoint",
"RawPath" : "",
"User" : null,
"ForceQuery" : false,
"Host" : "relays.syncthing.net",
"Opaque" : ""
},
"wan" : [
{
"ForceQuery" : false,
"User" : null,
"Host" : "31.15.66.212:443",
"Opaque" : "",
"Path" : "/",
"RawPath" : "",
"RawQuery" : "id=F4HSJVO\-CP2C3IL\-YLQYLSU\-XTYODAG\-PPU4LGV\-PH3MU4N\-G6K56DV\-IPN47A&pingInterval=1m0s&networkTimeout=2m0s&sessionLimitBps=0&globalLimitBps=0&statusAddr=:22070&providedBy=",
"Scheme" : "relay",
"Fragment" : ""
}
],
"lan" : [
{
"RawQuery" : "id=F4HSJVO\-CP2C3IL\-YLQYLSU\-XTYODAG\-PPU4LGV\-PH3MU4N\-G6K56DV\-IPN47A&pingInterval=1m0s&networkTimeout=2m0s&sessionLimitBps=0&globalLimitBps=0&statusAddr=:22070&providedBy=",
"Scheme" : "relay",
"Fragment" : "",
"RawPath" : "",
"Path" : "/",
"Host" : "31.15.66.212:443",
"Opaque" : "",
"ForceQuery" : false,
"User" : null
}
]
}
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS LocalChangeDetected
.sp
Generated upon scan whenever the local disk has discovered an updated file from the
previous scan. This does NOT include events that are discovered and copied from
other devices, only files that were changed on the local filesystem.
previous scan. This does \fInot\fP include events that are discovered and copied from
other devices (remote\-change\-detected), only files that were changed on the
local filesystem.
.INDENT 0.0
.INDENT 3.5
.sp
@@ -619,6 +707,85 @@ changes during a scan.
.fi
.UNINDENT
.UNINDENT
.SS Login Attempt
.sp
When authentication is enabled for the GUI, this event is emitted on every
login attempt. If either the username or password are incorrect, \fBsuccess\fP
is false and in any case the given username is returned.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"id" : 187,
"time" : "2017\-03\-07T00:19:24.420386143+01:00",
"data" : {
"username" : "somename",
"success" : false
},
"type" : "LoginAttempt",
"globalID" : 195
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS RemoteChangeDetected
.sp
Generated upon scan whenever a file is locally updated due to a remote change.
Files that are updated locally produce a local\-change\-detected event.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"time" : "2017\-03\-06T23:58:21.844739891+01:00",
"globalID" : 123,
"data" : {
"type" : "file",
"action" : "deleted",
"path" : "/media/ntfs_data/Dokumente/testfile",
"label" : "Dokumente",
"folderID" : "Dokumente",
"modifiedBy" : "BPDFDTU"
},
"type" : "RemoteChangeDetected",
"id" : 2
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS Remote Download Progress
.sp
This event is emitted when a download\-progress message is
received. It returns a map \fBdata\fP of filenames with a count of
downloaded blocks. The files in questions are currently being
downloaded on the remote \fBdevice\fP and belong to \fBfolder\fP\&.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"time" : "2017\-03\-07T00:11:37.65838955+01:00",
"globalID" : 170,
"data" : {
"state" : {
"tahr64\-6.0.5.iso" : 1784
},
"device" : "F4HSJVO\-CP2C3IL\-YLQYLSU\-XTYODAG\-PPU4LGV\-PH3MU4N\-G6K56DV\-IPN47A",
"folder" : "Dokumente"
},
"type" : "RemoteDownloadProgress",
"id" : 163
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS RemoteIndexUpdated
.sp
Generated each time new index information is received from a device.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-FAQ" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-FAQ" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-faq \- Frequently Asked Questions
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-GLOBALDISCO" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-GLOBALDISCO" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-globaldisco \- Global Discovery Protocol v3
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-LOCALDISCO" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-LOCALDISCO" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-localdisco \- Local Discovery Protocol v4
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-NETWORKING" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-NETWORKING" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-networking \- Firewall Setup
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-RELAY" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-RELAY" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-relay \- Relay Protocol v1
.
+188 -16
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-REST-API" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-REST-API" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-rest-api \- REST API
.
@@ -404,9 +404,11 @@ Returns the list of recent log entries.
.UNINDENT
.SS POST /rest/system/pause
.sp
Pause the given device.
Pause the given device or all devices.
.sp
Takes the mandatory \fBdevice\fP parameter and returns status 200 and no content upon success, or status 500 and a plain text error on failure.
Takes the optional parameter \fBdevice\fP (device ID). When ommitted,
pauses all devices. Returns status 200 and no content upon success, or status
500 and a plain text error on failure.
.SS GET /rest/system/ping
.sp
Returns a \fB{"ping": "pong"}\fP object.
@@ -446,9 +448,11 @@ $ curl \-X POST \-H "X\-API\-Key: abc123" http://localhost:8384/rest/system/rese
Post with empty body to immediately restart Syncthing.
.SS POST /rest/system/resume
.sp
Resume the given device.
Resume the given device or all devices.
.sp
Takes the mandatory \fBdevice\fP parameter and returns status 200 and no content upon success, or status 500 and a plain text error on failure.
Takes the optional parameter \fBdevice\fP (device ID). When ommitted,
resumes all devices. Returns status 200 and no content upon success, or status
500 and a plain text error on failure.
.SS POST /rest/system/shutdown
.sp
Post with empty body to cause Syncthing to exit and not restart.
@@ -878,13 +882,17 @@ This is an expensive call, increasing CPU and RAM usage on the device. Use spari
Syncthing provides a simple long polling interface for exposing events from the
core utility towards a GUI.
.sp
To receive events, perform a HTTP GET of \fB/rest/events?since=<lastSeenID>\fP,
where \fB<lastSeenID>\fP is the ID of the last event you\(aqve already seen or zero.
Syncthing returns a JSON encoded array of event objects, starting at the event
just after the one with the last seen ID. There is a limit to the number of
events buffered, so if the rate of events is high or the time between polling
calls is long some events might be missed. This can be detected by noting a
discontinuity in the event IDs.
To receive events, perform a HTTP GET of \fB/rest/events\fP or
\fB/rest/events/disk\fP\&. The latter returns only local\-change\-detected and
local\-change\-detected events, the former all other events.
.sp
The optional parameter \fBsince=<lastSeenID>\fP sets the ID of the last event
you\(aqve already seen. Syncthing returns a JSON encoded array of event objects,
starting at the event just after the one with this last seen ID. The default
value is 0, which returns all events. There is a limit to the number of events
buffered, so if the rate of events is high or the time between polling calls is
long some events might be missed. This can be detected by noting a discontinuity
in the event IDs.
.sp
If no new events are produced since \fB<lastSeenID>\fP, the HTTP call blocks and
waits for new events to happen before returning. By default it times out after
@@ -1292,6 +1300,32 @@ have, or have but do not share with the device in question.
.fi
.UNINDENT
.UNINDENT
.SS Folder Scan Progress
.sp
Emitted in regular intervals (folder setting ProgressIntervalS, 2s by default)
during scans giving the amount of bytes already scanned and to be scanned in
total , as well as the current scanning rates in bytes per second.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"data" : {
"total" : 1,
"rate" : 0,
"current" : 0,
"folder" : "bd7q3\-zskm5"
},
"globalID" : 29,
"type" : "FolderScanProgress",
"time" : "2017\-03\-06T15:00:58.072004209+01:00",
"id" : 29
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS FolderSummary
.sp
The FolderSummary event is emitted when folder contents have changed
@@ -1412,11 +1446,69 @@ The \fBaction\fP field is either \fBupdate\fP (contents changed), \fBmetadata\fP
.sp
New in version 0.11.10: The \fBmetadata\fP action.
.SS Listen Addresses Changed
.sp
This event is emitted when a listen address changes.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"type" : "ListenAddressesChanged",
"id" : 70,
"time" : "2017\-03\-06T15:01:24.88340663+01:00",
"globalID" : 70,
"data" : {
"address" : {
"Fragment" : "",
"RawQuery" : "",
"Scheme" : "dynamic+https",
"Path" : "/endpoint",
"RawPath" : "",
"User" : null,
"ForceQuery" : false,
"Host" : "relays.syncthing.net",
"Opaque" : ""
},
"wan" : [
{
"ForceQuery" : false,
"User" : null,
"Host" : "31.15.66.212:443",
"Opaque" : "",
"Path" : "/",
"RawPath" : "",
"RawQuery" : "id=F4HSJVO\-CP2C3IL\-YLQYLSU\-XTYODAG\-PPU4LGV\-PH3MU4N\-G6K56DV\-IPN47A&pingInterval=1m0s&networkTimeout=2m0s&sessionLimitBps=0&globalLimitBps=0&statusAddr=:22070&providedBy=",
"Scheme" : "relay",
"Fragment" : ""
}
],
"lan" : [
{
"RawQuery" : "id=F4HSJVO\-CP2C3IL\-YLQYLSU\-XTYODAG\-PPU4LGV\-PH3MU4N\-G6K56DV\-IPN47A&pingInterval=1m0s&networkTimeout=2m0s&sessionLimitBps=0&globalLimitBps=0&statusAddr=:22070&providedBy=",
"Scheme" : "relay",
"Fragment" : "",
"RawPath" : "",
"Path" : "/",
"Host" : "31.15.66.212:443",
"Opaque" : "",
"ForceQuery" : false,
"User" : null
}
]
}
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS LocalChangeDetected
.sp
Generated upon scan whenever the local disk has discovered an updated file from the
previous scan. This does NOT include events that are discovered and copied from
other devices, only files that were changed on the local filesystem.
previous scan. This does \fInot\fP include events that are discovered and copied from
other devices (remote\-change\-detected), only files that were changed on the
local filesystem.
.INDENT 0.0
.INDENT 3.5
.sp
@@ -1462,6 +1554,85 @@ changes during a scan.
.fi
.UNINDENT
.UNINDENT
.SS Login Attempt
.sp
When authentication is enabled for the GUI, this event is emitted on every
login attempt. If either the username or password are incorrect, \fBsuccess\fP
is false and in any case the given username is returned.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"id" : 187,
"time" : "2017\-03\-07T00:19:24.420386143+01:00",
"data" : {
"username" : "somename",
"success" : false
},
"type" : "LoginAttempt",
"globalID" : 195
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS RemoteChangeDetected
.sp
Generated upon scan whenever a file is locally updated due to a remote change.
Files that are updated locally produce a local\-change\-detected event.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"time" : "2017\-03\-06T23:58:21.844739891+01:00",
"globalID" : 123,
"data" : {
"type" : "file",
"action" : "deleted",
"path" : "/media/ntfs_data/Dokumente/testfile",
"label" : "Dokumente",
"folderID" : "Dokumente",
"modifiedBy" : "BPDFDTU"
},
"type" : "RemoteChangeDetected",
"id" : 2
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS Remote Download Progress
.sp
This event is emitted when a download\-progress message is
received. It returns a map \fBdata\fP of filenames with a count of
downloaded blocks. The files in questions are currently being
downloaded on the remote \fBdevice\fP and belong to \fBfolder\fP\&.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
{
"time" : "2017\-03\-07T00:11:37.65838955+01:00",
"globalID" : 170,
"data" : {
"state" : {
"tahr64\-6.0.5.iso" : 1784
},
"device" : "F4HSJVO\-CP2C3IL\-YLQYLSU\-XTYODAG\-PPU4LGV\-PH3MU4N\-G6K56DV\-IPN47A",
"folder" : "Dokumente"
},
"type" : "RemoteDownloadProgress",
"id" : 163
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS RemoteIndexUpdated
.sp
Generated each time new index information is received from a device.
@@ -1555,8 +1726,7 @@ seconds and is now in state \fBidle\fP\&.
.sp
Returns local disk events that occur when the scanner detects local file system
changes (local\-change\-detected) or when files are pulled from a remote
device. In addition it returns ping events, such that this request
returns after a minute, at the latest.
device (remote\-change\-detected).
.INDENT 0.0
.TP
.B Optional GET parameters:
@@ -1564,6 +1734,8 @@ returns after a minute, at the latest.
.IP \(bu 2
since (events starting after the given ID)
.IP \(bu 2
timeout (fail after given seconds if no event is available, 2s by default)
.IP \(bu 2
limit (return last x number of events)
.UNINDENT
.UNINDENT
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-SECURITY" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-SECURITY" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-security \- Security Principles
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-STIGNORE" "5" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-STIGNORE" "5" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-stignore \- Prevent files from being synchronized to other nodes
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING-VERSIONING" "7" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING-VERSIONING" "7" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing-versioning \- Keep automatic backups of deleted files by other nodes
.
+1 -1
View File
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SYNCTHING" "1" "March 13, 2017" "v0.14" "Syncthing"
.TH "SYNCTHING" "1" "March 31, 2017" "v0.14" "Syncthing"
.SH NAME
syncthing \- Syncthing
.
+5
View File
@@ -50,6 +50,11 @@ func generalNode(n *html.Node, filename string) {
if matches := attrRe.FindStringSubmatch(a.Val); len(matches) == 2 {
translation(matches[1])
}
if a.Key == "data-content" &&
!noStringRe.MatchString(a.Val) {
log.Println("Untranslated data-content string (" + filename + "):")
log.Print("\t" + a.Val)
}
}
}
}
-71
View File
@@ -1,71 +0,0 @@
go-lz4
======
go-lz4 is port of LZ4 lossless compression algorithm to Go. The original C code
is located at:
https://github.com/Cyan4973/lz4
Status
------
[![Build Status](https://secure.travis-ci.org/bkaradzic/go-lz4.png)](http://travis-ci.org/bkaradzic/go-lz4)
[![GoDoc](https://godoc.org/github.com/bkaradzic/go-lz4?status.png)](https://godoc.org/github.com/bkaradzic/go-lz4)
Usage
-----
go get github.com/bkaradzic/go-lz4
import "github.com/bkaradzic/go-lz4"
The package name is `lz4`
Notes
-----
* go-lz4 saves a uint32 with the original uncompressed length at the beginning
of the encoded buffer. They may get in the way of interoperability with
other implementations.
Contributors
------------
Damian Gryski ([@dgryski](https://github.com/dgryski))
Dustin Sallings ([@dustin](https://github.com/dustin))
Contact
-------
[@bkaradzic](https://twitter.com/bkaradzic)
http://www.stuckingeometry.com
Project page
https://github.com/bkaradzic/go-lz4
License
-------
Copyright 2011-2012 Branimir Karadzic. All rights reserved.
Copyright 2013 Damian Gryski. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
-63
View File
@@ -1,63 +0,0 @@
package lz4
import (
"bytes"
"io/ioutil"
"testing"
)
var testfile, _ = ioutil.ReadFile("testdata/pg1661.txt")
func roundtrip(t *testing.T, input []byte) {
dst, err := Encode(nil, input)
if err != nil {
t.Errorf("got error during compression: %s", err)
}
output, err := Decode(nil, dst)
if err != nil {
t.Errorf("got error during decompress: %s", err)
}
if !bytes.Equal(output, input) {
t.Errorf("roundtrip failed")
}
}
func TestEmpty(t *testing.T) {
roundtrip(t, nil)
}
func TestLengths(t *testing.T) {
for i := 0; i < 1024; i++ {
roundtrip(t, testfile[:i])
}
for i := 1024; i < 4096; i += 23 {
roundtrip(t, testfile[:i])
}
}
func TestWords(t *testing.T) {
roundtrip(t, testfile)
}
func BenchmarkLZ4Encode(b *testing.B) {
for i := 0; i < b.N; i++ {
Encode(nil, testfile)
}
}
func BenchmarkLZ4Decode(b *testing.B) {
var compressed, _ = Encode(nil, testfile)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Decode(nil, compressed)
}
}
File diff suppressed because it is too large Load Diff
-14
View File
@@ -1,14 +0,0 @@
du
==
Get total and available disk space on a given volume.
Documentation
-------------
http://godoc.org/github.com/calmh/du
License
-------
Public Domain
+9 -2
View File
@@ -1,6 +1,7 @@
package du
import (
"runtime"
"syscall"
"unsafe"
)
@@ -13,14 +14,20 @@ func Get(path string) (Usage, error) {
var u Usage
pathw, err := syscall.UTF16PtrFromString(path)
if err != nil {
return Usage{}, err
}
ret, _, err := c.Call(
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))),
uintptr(unsafe.Pointer(pathw)),
uintptr(unsafe.Pointer(&u.FreeBytes)),
uintptr(unsafe.Pointer(&u.TotalBytes)),
uintptr(unsafe.Pointer(&u.AvailBytes)))
runtime.KeepAlive(pathw)
if ret == 0 {
return u, err
return Usage{}, err
}
return u, nil
-59
View File
@@ -1,59 +0,0 @@
// Copyright (C) 2014 Jakob Borg
package luhn_test
import (
"testing"
"github.com/calmh/luhn"
)
func TestGenerate(t *testing.T) {
// Base 6 Luhn
a := luhn.Alphabet("abcdef")
c, err := a.Generate("abcdef")
if err != nil {
t.Fatal(err)
}
if c != 'e' {
t.Errorf("Incorrect check digit %c != e", c)
}
// Base 10 Luhn
a = luhn.Alphabet("0123456789")
c, err = a.Generate("7992739871")
if err != nil {
t.Fatal(err)
}
if c != '3' {
t.Errorf("Incorrect check digit %c != 3", c)
}
}
func TestInvalidString(t *testing.T) {
a := luhn.Alphabet("ABC")
_, err := a.Generate("7992739871")
t.Log(err)
if err == nil {
t.Error("Unexpected nil error")
}
}
func TestBadAlphabet(t *testing.T) {
a := luhn.Alphabet("01234566789")
_, err := a.Generate("7992739871")
t.Log(err)
if err == nil {
t.Error("Unexpected nil error")
}
}
func TestValidate(t *testing.T) {
a := luhn.Alphabet("abcdef")
if !a.Validate("abcdefe") {
t.Errorf("Incorrect validation response for abcdefe")
}
if a.Validate("abcdefd") {
t.Errorf("Incorrect validation response for abcdefd")
}
}
-10
View File
@@ -1,10 +0,0 @@
xdr
===
[![Build Status](https://img.shields.io/circleci/project/calmh/xdr.svg?style=flat-square)](https://circleci.com/gh/calmh/xdr)
[![Coverage Status](https://img.shields.io/coveralls/calmh/xdr.svg?style=flat)](https://coveralls.io/r/calmh/xdr?branch=master)
[![API Documentation](http://img.shields.io/badge/api-Godoc-blue.svg?style=flat)](http://godoc.org/github.com/calmh/xdr)
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://opensource.org/licenses/MIT)
This is an XDR marshalling/unmarshalling library. It uses code generation and
not reflection.
-52
View File
@@ -1,52 +0,0 @@
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
// is governed by an MIT-style license that can be found in the LICENSE file.
package xdr_test
import "testing"
type XDRBenchStruct struct {
I1 uint64
I2 uint32
I3 uint16
I4 uint8
Bs0 []byte // max:128
Bs1 []byte
Is0 []int32
S0 string // max:128
S1 string
}
var res []byte // not to be optimized away
var s = XDRBenchStruct{
I1: 42,
I2: 43,
I3: 44,
I4: 45,
Bs0: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18},
Bs1: []byte{11, 12, 13, 14, 15, 16, 17, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
Is0: []int32{23, 43},
S0: "Hello World! String one.",
S1: "Hello World! String two.",
}
func BenchmarkThisMarshal(b *testing.B) {
for i := 0; i < b.N; i++ {
res, _ = s.MarshalXDR()
}
b.ReportAllocs()
}
func BenchmarkThisUnmarshal(b *testing.B) {
bs := s.MustMarshalXDR()
var t XDRBenchStruct
for i := 0; i < b.N; i++ {
err := t.UnmarshalXDR(bs)
if err != nil {
b.Fatal(err)
}
}
b.ReportAllocs()
}
-140
View File
@@ -1,140 +0,0 @@
// ************************************************************
// This file is automatically generated by genxdr. Do not edit.
// ************************************************************
package xdr_test
import (
"github.com/calmh/xdr"
)
/*
XDRBenchStruct Structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ I1 (64 bits) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| I2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 16 zero bits | I3 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 24 zero bits | I4 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ Bs0 (length + padded data) \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ Bs1 (length + padded data) \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Number of Is0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
| Is0 (n items) |
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ S0 (length + padded data) \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ S1 (length + padded data) \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
struct XDRBenchStruct {
unsigned hyper I1;
unsigned int I2;
unsigned int I3;
unsigned int I4;
opaque Bs0<128>;
opaque Bs1<>;
int Is0<>;
string S0<128>;
string S1<>;
}
*/
func (o XDRBenchStruct) XDRSize() int {
return 8 + 4 + 4 + 4 +
4 + len(o.Bs0) + xdr.Padding(len(o.Bs0)) +
4 + len(o.Bs1) + xdr.Padding(len(o.Bs1)) +
4 + len(o.Is0)*4 +
4 + len(o.S0) + xdr.Padding(len(o.S0)) +
4 + len(o.S1) + xdr.Padding(len(o.S1))
}
func (o XDRBenchStruct) MarshalXDR() ([]byte, error) {
buf := make([]byte, o.XDRSize())
m := &xdr.Marshaller{Data: buf}
return buf, o.MarshalXDRInto(m)
}
func (o XDRBenchStruct) MustMarshalXDR() []byte {
bs, err := o.MarshalXDR()
if err != nil {
panic(err)
}
return bs
}
func (o XDRBenchStruct) MarshalXDRInto(m *xdr.Marshaller) error {
m.MarshalUint64(o.I1)
m.MarshalUint32(o.I2)
m.MarshalUint16(o.I3)
m.MarshalUint8(o.I4)
if l := len(o.Bs0); l > 128 {
return xdr.ElementSizeExceeded("Bs0", l, 128)
}
m.MarshalBytes(o.Bs0)
m.MarshalBytes(o.Bs1)
m.MarshalUint32(uint32(len(o.Is0)))
for i := range o.Is0 {
m.MarshalUint32(uint32(o.Is0[i]))
}
if l := len(o.S0); l > 128 {
return xdr.ElementSizeExceeded("S0", l, 128)
}
m.MarshalString(o.S0)
m.MarshalString(o.S1)
return m.Error
}
func (o *XDRBenchStruct) UnmarshalXDR(bs []byte) error {
u := &xdr.Unmarshaller{Data: bs}
return o.UnmarshalXDRFrom(u)
}
func (o *XDRBenchStruct) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
o.I1 = u.UnmarshalUint64()
o.I2 = u.UnmarshalUint32()
o.I3 = u.UnmarshalUint16()
o.I4 = u.UnmarshalUint8()
o.Bs0 = u.UnmarshalBytesMax(128)
o.Bs1 = u.UnmarshalBytes()
_Is0Size := int(u.UnmarshalUint32())
if _Is0Size < 0 {
return xdr.ElementSizeExceeded("Is0", _Is0Size, 0)
} else if _Is0Size == 0 {
o.Is0 = nil
} else {
if _Is0Size <= len(o.Is0) {
o.Is0 = o.Is0[:_Is0Size]
} else {
o.Is0 = make([]int32, _Is0Size)
}
for i := range o.Is0 {
o.Is0[i] = int32(u.UnmarshalUint32())
}
}
o.S0 = u.UnmarshalStringMax(128)
o.S1 = u.UnmarshalString()
return u.Error
}
-3
View File
@@ -1,3 +0,0 @@
dependencies:
post:
- ./generate.sh
-241
View File
@@ -1,241 +0,0 @@
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
// is governed by an MIT-style license that can be found in the LICENSE file.
package xdr_test
import (
"bytes"
"io"
"log"
"math/rand"
"reflect"
"testing"
"testing/quick"
"github.com/calmh/xdr"
)
// Contains all supported types
type TestStruct struct {
B bool
I int
I8 int8
UI8 uint8
I16 int16
UI16 uint16
I32 int32
UI32 uint32
I64 int64
UI64 uint64
BS []byte // max:1024
S string // max:1024
C Opaque
SS []string // max:1024
ES EmptyStruct
OS OtherStruct
OSs []OtherStruct
}
func (s1 TestStruct) TestEquals(s2 TestStruct) bool {
if s1.B != s2.B {
log.Printf("B differ; %v != %v", s1.B, s2.B)
return false
}
if s1.I != s2.I {
log.Printf("I differ; %d != %d", s1.I, s2.I)
return false
}
if s1.I8 != s2.I8 {
log.Printf("I8 differ; %d != %d", s1.I8, s2.I8)
return false
}
if s1.UI8 != s2.UI8 {
log.Printf("UI8 differ; %d != %d", s1.UI8, s2.UI8)
return false
}
if s1.I16 != s2.I16 {
log.Printf("I16 differ; %d != %d", s1.I16, s2.I16)
return false
}
if s1.UI16 != s2.UI16 {
log.Printf("UI16 differ; %d != %d", s1.UI16, s2.UI16)
return false
}
if s1.I32 != s2.I32 {
log.Printf("I32 differ; %d != %d", s1.I32, s2.I32)
return false
}
if s1.UI32 != s2.UI32 {
log.Printf("UI32 differ; %d != %d", s1.UI32, s2.UI32)
return false
}
if s1.I64 != s2.I64 {
log.Printf("I64 differ; %d != %d", s1.I64, s2.I64)
return false
}
if s1.UI64 != s2.UI64 {
log.Printf("UI64 differ; %d != %d", s1.UI64, s2.UI64)
return false
}
if !bytes.Equal(s1.BS, s2.BS) {
log.Println("BS differ")
return false
}
if s1.S != s2.S {
log.Printf("S differ; %q != %q", s1.S, s2.S)
return false
}
if s1.C != s2.C {
log.Printf("C differ; %q != %q", s1.C, s2.C)
return false
}
if len(s1.SS) != len(s2.SS) {
log.Printf("len(SS) differ; %q != %q", len(s1.SS), len(s2.SS))
return false
}
for i := range s1.SS {
if s1.SS[i] != s2.SS[i] {
log.Printf("SS[%d] differ; %q != %q", i, s1.SS[i], s2.SS[i])
return false
}
}
if s1.OS != s2.OS {
log.Printf("OS differ; %q != %q", s1.OS, s2.OS)
return false
}
if len(s1.OSs) != len(s2.OSs) {
log.Printf("len(OSs) differ; %q != %q", len(s1.OSs), len(s2.OSs))
return false
}
for i := range s1.OSs {
if s1.OSs[i] != s2.OSs[i] {
log.Printf("OSs[%d] differ; %q != %q", i, s1.OSs[i], s2.OSs[i])
return false
}
}
return true
}
type EmptyStruct struct {
}
type OtherStruct struct {
F1 uint32
F2 string
}
type Opaque [32]byte
func (u *Opaque) XDRSize() int {
return 32
}
func (u *Opaque) MarshalXDRInto(m *xdr.Marshaller) error {
m.MarshalRaw(u[:])
return m.Error
}
func (o *Opaque) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
copy((*o)[:], u.UnmarshalRaw(32))
return u.Error
}
func (Opaque) Generate(rand *rand.Rand, size int) reflect.Value {
var u Opaque
for i := range u[:] {
u[i] = byte(rand.Int())
}
return reflect.ValueOf(u)
}
func TestEncDec(t *testing.T) {
fn := func(t0 TestStruct) bool {
bs, err := t0.MarshalXDR()
if err != nil {
t.Fatal(err)
}
var t1 TestStruct
err = t1.UnmarshalXDR(bs)
if err != nil {
t.Fatal(err)
}
return t0.TestEquals(t1)
}
if err := quick.Check(fn, nil); err != nil {
t.Error(err)
}
}
func TestMarshalShortBuffer(t *testing.T) {
var s TestStruct
buf := make([]byte, s.XDRSize())
if err := s.MarshalXDRInto(&xdr.Marshaller{Data: buf}); err != nil {
t.Fatal("Unexpected error", err)
}
if err := s.MarshalXDRInto(&xdr.Marshaller{Data: buf[1:]}); err != io.ErrShortBuffer {
t.Fatal("Expected io.ErrShortBuffer, got", err)
}
}
func TestUnmarshalUnexpectedEOF(t *testing.T) {
var s TestStruct
buf := make([]byte, s.XDRSize())
if err := s.MarshalXDRInto(&xdr.Marshaller{Data: buf}); err != nil {
t.Fatal("Unexpected error", err)
}
if err := s.UnmarshalXDR(buf[:len(buf)-1]); err != io.ErrUnexpectedEOF {
t.Fatal("Expected io.ErrUnexpectedEOF, got", err)
}
u := &xdr.Unmarshaller{Data: buf[:3]}
u.UnmarshalRaw(4)
if err := u.Error; err != io.ErrUnexpectedEOF {
t.Fatal("Expected io.ErrUnexpectedEOF, got", err)
}
u = &xdr.Unmarshaller{Data: buf[:3]}
u.UnmarshalString()
if err := u.Error; err != io.ErrUnexpectedEOF {
t.Fatal("Expected io.ErrUnexpectedEOF, got", err)
}
u = &xdr.Unmarshaller{Data: buf[:3]}
u.UnmarshalBytes()
if err := u.Error; err != io.ErrUnexpectedEOF {
t.Fatal("Expected io.ErrUnexpectedEOF, got", err)
}
u = &xdr.Unmarshaller{Data: buf[:3]}
u.UnmarshalBool()
if err := u.Error; err != io.ErrUnexpectedEOF {
t.Fatal("Expected io.ErrUnexpectedEOF, got", err)
}
u = &xdr.Unmarshaller{Data: buf[:3]}
u.UnmarshalUint8()
if err := u.Error; err != io.ErrUnexpectedEOF {
t.Fatal("Expected io.ErrUnexpectedEOF, got", err)
}
u = &xdr.Unmarshaller{Data: buf[:3]}
u.UnmarshalUint16()
if err := u.Error; err != io.ErrUnexpectedEOF {
t.Fatal("Expected io.ErrUnexpectedEOF, got", err)
}
u = &xdr.Unmarshaller{Data: buf[:3]}
u.UnmarshalUint32()
if err := u.Error; err != io.ErrUnexpectedEOF {
t.Fatal("Expected io.ErrUnexpectedEOF, got", err)
}
u = &xdr.Unmarshaller{Data: buf[:7]}
u.UnmarshalUint64()
if err := u.Error; err != io.ErrUnexpectedEOF {
t.Fatal("Expected io.ErrUnexpectedEOF, got", err)
}
}
-319
View File
@@ -1,319 +0,0 @@
// ************************************************************
// This file is automatically generated by genxdr. Do not edit.
// ************************************************************
package xdr_test
import (
"github.com/calmh/xdr"
)
/*
TestStruct Structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| B (V=0 or 1) |V|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ int Structure \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 24 zero bits | I8 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 24 zero bits | UI8 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 16 zero bits | I16 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 16 zero bits | UI16 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| I32 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UI32 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ I64 (64 bits) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ UI64 (64 bits) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ BS (length + padded data) \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ S (length + padded data) \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ Opaque Structure \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Number of SS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ /
\ SS (length + padded data) \
/ /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ EmptyStruct Structure \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ OtherStruct Structure \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Number of OSs |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ Zero or more OtherStruct Structures \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
struct TestStruct {
bool B;
int I;
int I8;
unsigned int UI8;
int I16;
unsigned int UI16;
int I32;
unsigned int UI32;
hyper I64;
unsigned hyper UI64;
opaque BS<1024>;
string S<1024>;
Opaque C;
string SS<1024>;
EmptyStruct ES;
OtherStruct OS;
OtherStruct OSs<>;
}
*/
func (o TestStruct) XDRSize() int {
return 4 + 8 + 4 + 4 + 4 + 4 + 4 + 4 + 8 + 8 +
4 + len(o.BS) + xdr.Padding(len(o.BS)) +
4 + len(o.S) + xdr.Padding(len(o.S)) +
o.C.XDRSize() +
4 + xdr.SizeOfSlice(o.SS) +
o.ES.XDRSize() +
o.OS.XDRSize() +
4 + xdr.SizeOfSlice(o.OSs)
}
func (o TestStruct) MarshalXDR() ([]byte, error) {
buf := make([]byte, o.XDRSize())
m := &xdr.Marshaller{Data: buf}
return buf, o.MarshalXDRInto(m)
}
func (o TestStruct) MustMarshalXDR() []byte {
bs, err := o.MarshalXDR()
if err != nil {
panic(err)
}
return bs
}
func (o TestStruct) MarshalXDRInto(m *xdr.Marshaller) error {
m.MarshalBool(o.B)
m.MarshalUint64(uint64(o.I))
m.MarshalUint8(uint8(o.I8))
m.MarshalUint8(o.UI8)
m.MarshalUint16(uint16(o.I16))
m.MarshalUint16(o.UI16)
m.MarshalUint32(uint32(o.I32))
m.MarshalUint32(o.UI32)
m.MarshalUint64(uint64(o.I64))
m.MarshalUint64(o.UI64)
if l := len(o.BS); l > 1024 {
return xdr.ElementSizeExceeded("BS", l, 1024)
}
m.MarshalBytes(o.BS)
if l := len(o.S); l > 1024 {
return xdr.ElementSizeExceeded("S", l, 1024)
}
m.MarshalString(o.S)
if err := o.C.MarshalXDRInto(m); err != nil {
return err
}
if l := len(o.SS); l > 1024 {
return xdr.ElementSizeExceeded("SS", l, 1024)
}
m.MarshalUint32(uint32(len(o.SS)))
for i := range o.SS {
m.MarshalString(o.SS[i])
}
if err := o.ES.MarshalXDRInto(m); err != nil {
return err
}
if err := o.OS.MarshalXDRInto(m); err != nil {
return err
}
m.MarshalUint32(uint32(len(o.OSs)))
for i := range o.OSs {
if err := o.OSs[i].MarshalXDRInto(m); err != nil {
return err
}
}
return m.Error
}
func (o *TestStruct) UnmarshalXDR(bs []byte) error {
u := &xdr.Unmarshaller{Data: bs}
return o.UnmarshalXDRFrom(u)
}
func (o *TestStruct) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
o.B = u.UnmarshalBool()
o.I = int(u.UnmarshalUint64())
o.I8 = int8(u.UnmarshalUint8())
o.UI8 = u.UnmarshalUint8()
o.I16 = int16(u.UnmarshalUint16())
o.UI16 = u.UnmarshalUint16()
o.I32 = int32(u.UnmarshalUint32())
o.UI32 = u.UnmarshalUint32()
o.I64 = int64(u.UnmarshalUint64())
o.UI64 = u.UnmarshalUint64()
o.BS = u.UnmarshalBytesMax(1024)
o.S = u.UnmarshalStringMax(1024)
(&o.C).UnmarshalXDRFrom(u)
_SSSize := int(u.UnmarshalUint32())
if _SSSize < 0 {
return xdr.ElementSizeExceeded("SS", _SSSize, 1024)
} else if _SSSize == 0 {
o.SS = nil
} else {
if _SSSize > 1024 {
return xdr.ElementSizeExceeded("SS", _SSSize, 1024)
}
if _SSSize <= len(o.SS) {
for i := _SSSize; i < len(o.SS); i++ {
o.SS[i] = ""
}
o.SS = o.SS[:_SSSize]
} else {
o.SS = make([]string, _SSSize)
}
for i := range o.SS {
o.SS[i] = u.UnmarshalString()
}
}
(&o.ES).UnmarshalXDRFrom(u)
(&o.OS).UnmarshalXDRFrom(u)
_OSsSize := int(u.UnmarshalUint32())
if _OSsSize < 0 {
return xdr.ElementSizeExceeded("OSs", _OSsSize, 0)
} else if _OSsSize == 0 {
o.OSs = nil
} else {
if _OSsSize <= len(o.OSs) {
o.OSs = o.OSs[:_OSsSize]
} else {
o.OSs = make([]OtherStruct, _OSsSize)
}
for i := range o.OSs {
(&o.OSs[i]).UnmarshalXDRFrom(u)
}
}
return u.Error
}
/*
EmptyStruct Structure:
(contains no fields)
struct EmptyStruct {
}
*/
func (o EmptyStruct) XDRSize() int {
return 0
}
func (o EmptyStruct) MarshalXDR() ([]byte, error) {
return nil, nil
}
func (o EmptyStruct) MustMarshalXDR() []byte {
return nil
}
func (o EmptyStruct) MarshalXDRInto(m *xdr.Marshaller) error {
return nil
}
func (o *EmptyStruct) UnmarshalXDR(bs []byte) error {
return nil
}
func (o *EmptyStruct) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
return nil
}
/*
OtherStruct Structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| F1 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
\ F2 (length + padded data) \
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
struct OtherStruct {
unsigned int F1;
string F2<>;
}
*/
func (o OtherStruct) XDRSize() int {
return 4 +
4 + len(o.F2) + xdr.Padding(len(o.F2))
}
func (o OtherStruct) MarshalXDR() ([]byte, error) {
buf := make([]byte, o.XDRSize())
m := &xdr.Marshaller{Data: buf}
return buf, o.MarshalXDRInto(m)
}
func (o OtherStruct) MustMarshalXDR() []byte {
bs, err := o.MarshalXDR()
if err != nil {
panic(err)
}
return bs
}
func (o OtherStruct) MarshalXDRInto(m *xdr.Marshaller) error {
m.MarshalUint32(o.F1)
m.MarshalString(o.F2)
return m.Error
}
func (o *OtherStruct) UnmarshalXDR(bs []byte) error {
u := &xdr.Unmarshaller{Data: bs}
return o.UnmarshalXDRFrom(u)
}
func (o *OtherStruct) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
o.F1 = u.UnmarshalUint32()
o.F2 = u.UnmarshalString()
return u.Error
}
-4
View File
@@ -1,4 +0,0 @@
#!/bin/sh
go run cmd/genxdr/main.go -- bench_test.go > bench_xdr_test.go
go run cmd/genxdr/main.go -- encdec_test.go > encdec_xdr_test.go
-66
View File
@@ -1,66 +0,0 @@
go-stun
=======
[![Build Status](https://travis-ci.org/ccding/go-stun.svg?branch=master)]
(https://travis-ci.org/ccding/go-stun)
[![License](https://img.shields.io/badge/License-Apache%202.0-red.svg)]
(https://opensource.org/licenses/Apache-2.0)
[![GoDoc](https://godoc.org/github.com/ccding/go-stun?status.svg)]
(http://godoc.org/github.com/ccding/go-stun/stun)
[![Go Report Card](https://goreportcard.com/badge/github.com/ccding/go-stun)]
(https://goreportcard.com/report/github.com/ccding/go-stun)
go-stun is a STUN (RFC 3489, 5389) client implementation in golang
(a.k.a. UDP hole punching).
[RFC 3489](https://tools.ietf.org/html/rfc3489):
STUN - Simple Traversal of User Datagram Protocol (UDP)
Through Network Address Translators (NATs)
[RFC 5389](https://tools.ietf.org/html/rfc5389):
Session Traversal Utilities for NAT (STUN)
### Use the Command Line Tool
Simply run these commands (if you have installed golang and set `$GOPATH`)
```
go get github.com/ccding/go-stun
go-stun
```
or clone this repo and run these commands
```
go build
./go-stun
```
You will get the output like
```
NAT Type: Full cone NAT
External IP Family: 1
External IP: 166.111.4.100
External Port: 23009
```
You can use `-s` flag to use another STUN server, and use `-v` to work on
verbose mode.
```bash
> ./go-stun --help
Usage of ./go-stun:
-s string
server address (default "stun1.l.google.com:19302")
-v verbose mode
```
### Use the Library
The library `github.com/ccding/go-stun/stun` is extremely easy to use -- just
one line of code.
```go
import "github.com/ccding/go-stun/stun"
func main() {
nat, host, err := stun.NewClient().Discover()
}
```
More details please go to `main.go` and [GoDoc]
(http://godoc.org/github.com/ccding/go-stun/stun)
-56
View File
@@ -1,56 +0,0 @@
// Copyright 2013, Cong Ding. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// author: Cong Ding <dinggnu@gmail.com>
package main
import (
"flag"
"fmt"
"github.com/ccding/go-stun/stun"
)
func main() {
var serverAddr = flag.String("s", stun.DefaultServerAddr, "STUN server address")
var v = flag.Bool("v", false, "verbose mode")
var vv = flag.Bool("vv", false, "double verbose mode (includes -v)")
var vvv = flag.Bool("vvv", false, "triple verbose mode (includes -v and -vv)")
flag.Parse()
// Creates a STUN client. NewClientWithConnection can also be used if
// you want to handle the UDP listener by yourself.
client := stun.NewClient()
// The default addr (stun.DefaultServerAddr) will be used unless we
// call SetServerAddr.
client.SetServerAddr(*serverAddr)
// Non verbose mode will be used by default unless we call
// SetVerbose(true) or SetVVerbose(true).
client.SetVerbose(*v || *vv || *vvv)
client.SetVVerbose(*vv || *vvv)
// Discover the NAT and return the result.
nat, host, err := client.Discover()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("NAT Type:", nat)
if host != nil {
fmt.Println("External IP Family:", host.Family())
fmt.Println("External IP:", host.IP())
fmt.Println("External Port:", host.Port())
}
}

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