├── l10n ├── .gitkeep ├── no-php ├── no-php.license ├── an.json ├── an.js ├── ur_PK.json ├── fi.php ├── kn.json ├── hy.json ├── ms_MY.json ├── ur_PK.js ├── sr@latin.json ├── kab.json ├── kn.js ├── hy.js ├── ms_MY.js ├── kab.js ├── ta.json ├── ia.json ├── sr@latin.js ├── nn_NO.json ├── cy_GB.json ├── sk.php ├── ta.js ├── bn_BD.json ├── ia.js ├── lb.json ├── nn_NO.js ├── cy_GB.js ├── af.json ├── uz.json ├── bn_BD.js ├── lb.js ├── az.json ├── km.json ├── mn.json ├── id.json ├── af.js ├── uz.js ├── az.js ├── ka.json ├── mn.js ├── bs.json ├── km.js ├── id.js ├── oc.json ├── th.json ├── vi.json ├── es_NI.json ├── es_PA.json ├── es_PE.json ├── es_PR.json ├── es_PY.json ├── es_UY.json ├── ka.js ├── bs.js ├── si.json ├── oc.js ├── es_419.json ├── th.js ├── eo.json ├── es_NI.js ├── es_PA.js ├── es_PE.js ├── es_PR.js ├── es_PY.js ├── es_UY.js ├── vi.js ├── si.js ├── es_AR.json ├── es_419.js ├── eo.js ├── es_AR.js ├── ro.json ├── be.json ├── mk.json ├── ro.js ├── be.js ├── mk.js ├── ast.json ├── ast.js ├── br.json ├── br.js ├── pt_PT.json ├── pt_PT.js ├── sq.json ├── sq.js ├── ka_GE.json ├── ka_GE.js ├── lt_LT.json ├── lt_LT.js ├── lv.json ├── lv.js ├── fi.json ├── fi.js ├── is.json ├── es_CO.json ├── es_CR.json ├── es_DO.json ├── es_GT.json ├── es_HN.json ├── es_SV.json ├── is.js ├── es_CL.json ├── es_CO.js ├── es_CR.js ├── es_DO.js ├── es_GT.js ├── es_HN.js ├── es_SV.js ├── es_CL.js ├── sv.json ├── sv.js └── he.json ├── tests ├── data │ ├── foo.txt │ ├── kitten.inf │ ├── foo.txt.license │ ├── kitten.inf.license │ └── icap │ │ ├── null-body.txt │ │ ├── 403-response.txt.license │ │ ├── null-body.txt.license │ │ └── 403-response.txt ├── psalm-baseline.xml.license ├── avir.sh ├── psalm-baseline.xml ├── avirserver.php ├── TemporaryHome.php ├── ICAP │ ├── ICAPClientTest.php │ └── ResponseParserTest.php ├── bootstrap.php ├── Scanner │ ├── ScannerBaseTest.php │ ├── ScannerFactoryTest.php │ ├── ExternalKasperskyTest.php │ └── ICAPTest.php ├── phpunit.xml ├── Db │ ├── RuleTest.php │ └── ItemMapperTest.php ├── DummyClam.php └── TestBase.php ├── img ├── app.png ├── app.svg ├── shield-dark.svg ├── shield-red.svg └── shield-green.svg ├── screenshots ├── 1.png └── 1.png.license ├── .github ├── issue_template.md.license ├── CODEOWNERS ├── workflows │ ├── package.yml │ ├── reuse.yml │ ├── fixup.yml │ ├── lint-info-xml.yml │ ├── lint-php-cs.yml │ ├── phpunit-summary-when-unrelated.yml │ ├── lint-php.yml │ └── pr-feedback.yml ├── contributing.md └── issue_template.md ├── krankerl.toml ├── .nextcloudignore ├── .scrutinizer.yml ├── .tx └── config ├── .php-cs-fixer.dist.php ├── lib ├── Event │ ├── ScanStateEvent.php │ └── BeforeBackgroundScanEvent.php ├── Db │ ├── Item.php │ ├── Rule.php │ └── ItemMapper.php ├── Migration │ ├── CleanupCronTask.php │ ├── Version60100Date20250424072838.php │ ├── Install.php │ └── Version10400Date20180929132835.php ├── StatusFactory.php ├── Settings │ └── Admin.php ├── ICAP │ ├── IcapResponseStatus.php │ ├── IcapResponse.php │ ├── ICAPTlsClient.php │ └── ICAPClient.php ├── Activity │ ├── Setting.php │ └── Filter.php ├── Scanner │ ├── IScanner.php │ ├── ScannerFactory.php │ └── LocalClam.php ├── ItemFactory.php ├── Sabre │ └── PropfindPlugin.php ├── CallbackReadDataWrapper.php ├── Command │ ├── BackgroundScan.php │ ├── Mark.php │ └── Status.php └── Controller │ └── RuleController.php ├── templates └── notification.php ├── .gitignore ├── appinfo └── routes.php ├── composer.json ├── LICENSES └── MIT.txt ├── css └── settings.css ├── psalm.xml └── REUSE.toml /l10n/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /l10n/no-php: -------------------------------------------------------------------------------- 1 | . 2 | -------------------------------------------------------------------------------- /tests/data/foo.txt: -------------------------------------------------------------------------------- 1 | foo -------------------------------------------------------------------------------- /tests/data/kitten.inf: -------------------------------------------------------------------------------- 1 | We have a kitten inside -------------------------------------------------------------------------------- /img/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/files_antivirus/HEAD/img/app.png -------------------------------------------------------------------------------- /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/files_antivirus/HEAD/screenshots/1.png -------------------------------------------------------------------------------- /l10n/no-php.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2014 ownCloud, Inc. 2 | SPDX-License-Identifier: AGPL-3.0-only -------------------------------------------------------------------------------- /tests/data/foo.txt.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2015 ownCloud, Inc. 2 | SPDX-License-Identifier: AGPL-3.0-only 3 | -------------------------------------------------------------------------------- /tests/data/kitten.inf.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2015 ownCloud, Inc. 2 | SPDX-License-Identifier: AGPL-3.0-only -------------------------------------------------------------------------------- /tests/data/icap/null-body.txt: -------------------------------------------------------------------------------- 1 | ICAP/1.0 200 OK 2 | Encapsulated: null-body=0 3 | ISTag: "b9eb4f031598bb0b-1716440776" 4 | -------------------------------------------------------------------------------- /.github/issue_template.md.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors 2 | SPDX-License-Identifier: MIT 3 | -------------------------------------------------------------------------------- /screenshots/1.png.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors 2 | SPDX-License-Identifier: AGPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /tests/psalm-baseline.xml.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors 2 | SPDX-License-Identifier: AGPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /tests/data/icap/403-response.txt.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors 2 | SPDX-License-Identifier: AGPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /tests/data/icap/null-body.txt.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors 2 | SPDX-License-Identifier: AGPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | 4 | # App maintainers 5 | -------------------------------------------------------------------------------- /l10n/an.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Host" : "Host", 3 | "Port" : "Puerto", 4 | "Yes" : "Si", 5 | "No" : "No" 6 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 7 | } -------------------------------------------------------------------------------- /krankerl.toml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | [package] 4 | before_cmds = [ 5 | 6 | ] 7 | -------------------------------------------------------------------------------- /l10n/an.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Host" : "Host", 5 | "Port" : "Puerto", 6 | "Yes" : "Si", 7 | "No" : "No" 8 | }, 9 | "nplurals=2; plural=(n != 1);"); 10 | -------------------------------------------------------------------------------- /l10n/ur_PK.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select" : "Select", 3 | "Yes" : "ہاں", 4 | "No" : "نہیں", 5 | "Save" : "حفظ", 6 | "Advanced" : "ایڈوانسڈ", 7 | "Description" : "تصریح" 8 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 9 | } -------------------------------------------------------------------------------- /l10n/fi.php: -------------------------------------------------------------------------------- 1 | "tallentaa" 9 | ); 10 | $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; 11 | -------------------------------------------------------------------------------- /l10n/kn.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "ಉಳಿಸಿದ", 3 | "Host" : "ಅತಿಥೆಯ-ಗಣಕ", 4 | "Port" : "ರೇವು", 5 | "Select" : "Select", 6 | "Yes" : "ಹೌದು", 7 | "No" : "ಇಲ್ಲ", 8 | "Save" : "ಉಳಿಸಿ" 9 | },"pluralForm" :"nplurals=2; plural=(n > 1);" 10 | } -------------------------------------------------------------------------------- /.nextcloudignore: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | /.git 4 | /.github 5 | /.gitignore 6 | /.nextcloudignore 7 | /.scrutinizer.yml 8 | /.tx 9 | /krankerl.toml 10 | /screenshots 11 | /tests 12 | -------------------------------------------------------------------------------- /l10n/hy.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "Պահված", 3 | "TLS" : "TLS", 4 | "Select" : "Select", 5 | "Yes" : "Այո", 6 | "No" : "Ոչ", 7 | "Save" : "Պահպանել", 8 | "Description" : "Նկարագրություն" 9 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 10 | } -------------------------------------------------------------------------------- /l10n/ms_MY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "Disimpan", 3 | "Select" : "Select", 4 | "Yes" : "Ya", 5 | "No" : "Tidak", 6 | "Save" : "Simpan", 7 | "Advanced" : "Maju", 8 | "Description" : "Keterangan" 9 | },"pluralForm" :"nplurals=1; plural=0;" 10 | } -------------------------------------------------------------------------------- /l10n/ur_PK.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Select" : "Select", 5 | "Yes" : "ہاں", 6 | "No" : "نہیں", 7 | "Save" : "حفظ", 8 | "Advanced" : "ایڈوانسڈ", 9 | "Description" : "تصریح" 10 | }, 11 | "nplurals=2; plural=(n != 1);"); 12 | -------------------------------------------------------------------------------- /tests/avir.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # SPDX-FileCopyrightText: 2014 ownCloud, Inc. 4 | # SPDX-License-Identifier: AGPL-3.0-only 5 | content=$(tee) 6 | 7 | if [[ $content =~ .*kitten ]]; then 8 | echo "Oh my god! : Kitten FOUND" 9 | exit 1 10 | fi 11 | 12 | echo "$1 : OK" 13 | -------------------------------------------------------------------------------- /l10n/sr@latin.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select" : "Obeleži", 3 | "Yes" : "Da", 4 | "No" : "Ne", 5 | "Save" : "Save", 6 | "Description" : "Opis" 7 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" 8 | } -------------------------------------------------------------------------------- /l10n/kab.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select" : "Fren", 3 | "Delete file" : "Kkes afaylu", 4 | "Yes" : "Ih", 5 | "No" : "Uhu", 6 | "Save" : "Sekles", 7 | "Advanced" : "Talqayt", 8 | "Description" : "Aglam" 9 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 10 | } -------------------------------------------------------------------------------- /l10n/kn.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "ಉಳಿಸಿದ", 5 | "Host" : "ಅತಿಥೆಯ-ಗಣಕ", 6 | "Port" : "ರೇವು", 7 | "Select" : "Select", 8 | "Yes" : "ಹೌದು", 9 | "No" : "ಇಲ್ಲ", 10 | "Save" : "ಉಳಿಸಿ" 11 | }, 12 | "nplurals=2; plural=(n > 1);"); 13 | -------------------------------------------------------------------------------- /l10n/hy.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "Պահված", 5 | "TLS" : "TLS", 6 | "Select" : "Select", 7 | "Yes" : "Այո", 8 | "No" : "Ոչ", 9 | "Save" : "Պահպանել", 10 | "Description" : "Նկարագրություն" 11 | }, 12 | "nplurals=2; plural=(n != 1);"); 13 | -------------------------------------------------------------------------------- /l10n/ms_MY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "Disimpan", 5 | "Select" : "Select", 6 | "Yes" : "Ya", 7 | "No" : "Tidak", 8 | "Save" : "Simpan", 9 | "Advanced" : "Maju", 10 | "Description" : "Keterangan" 11 | }, 12 | "nplurals=1; plural=0;"); 13 | -------------------------------------------------------------------------------- /l10n/kab.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Select" : "Fren", 5 | "Delete file" : "Kkes afaylu", 6 | "Yes" : "Ih", 7 | "No" : "Uhu", 8 | "Save" : "Sekles", 9 | "Advanced" : "Talqayt", 10 | "Description" : "Aglam" 11 | }, 12 | "nplurals=2; plural=(n != 1);"); 13 | -------------------------------------------------------------------------------- /l10n/ta.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Host" : "ஓம்புனர்", 3 | "Port" : "துறை ", 4 | "Select" : "Select", 5 | "Yes" : "ஆம்", 6 | "No" : "இல்லை", 7 | "Save" : "சேமிக்க ", 8 | "Advanced" : "உயர்ந்த", 9 | "Description" : "விவரிப்பு" 10 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 11 | } -------------------------------------------------------------------------------- /l10n/ia.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Salveguardante...", 3 | "Saved" : "Salveguardate", 4 | "Host" : "Hospite", 5 | "Port" : "Porto", 6 | "Select" : "Selectionar", 7 | "Save" : "Salveguardar", 8 | "Description" : "Description" 9 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 10 | } -------------------------------------------------------------------------------- /l10n/sr@latin.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Select" : "Obeleži", 5 | "Yes" : "Da", 6 | "No" : "Ne", 7 | "Save" : "Save", 8 | "Description" : "Opis" 9 | }, 10 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); 11 | -------------------------------------------------------------------------------- /l10n/nn_NO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "Lagra", 3 | "Host" : "Tenar", 4 | "Port" : "Port", 5 | "Select" : "Vel", 6 | "Delete file" : "Slett fil", 7 | "Save" : "Lagre", 8 | "Advanced" : "Avansert", 9 | "Description" : "Skildring" 10 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 11 | } -------------------------------------------------------------------------------- /tests/psalm-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /l10n/cy_GB.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "Wedi'u cadw", 3 | "Select" : "Select", 4 | "Yes" : "Ie", 5 | "No" : "Na", 6 | "Save" : "Cadw", 7 | "Advanced" : "Uwch", 8 | "Description" : "Disgrifiad" 9 | },"pluralForm" :"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;" 10 | } -------------------------------------------------------------------------------- /l10n/sk.php: -------------------------------------------------------------------------------- 1 | "Uložiť", 9 | "Advanced" => "Pokročilé", 10 | "Description" => "Popis" 11 | ); 12 | $PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; 13 | -------------------------------------------------------------------------------- /l10n/ta.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Host" : "ஓம்புனர்", 5 | "Port" : "துறை ", 6 | "Select" : "Select", 7 | "Yes" : "ஆம்", 8 | "No" : "இல்லை", 9 | "Save" : "சேமிக்க ", 10 | "Advanced" : "உயர்ந்த", 11 | "Description" : "விவரிப்பு" 12 | }, 13 | "nplurals=2; plural=(n != 1);"); 14 | -------------------------------------------------------------------------------- /l10n/bn_BD.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "সংরক্ষণ করা হলো", 3 | "Host" : "হোস্ট", 4 | "Port" : "পোর্ট", 5 | "Select" : "সিলেক্ট", 6 | "Yes" : "হ্যাঁ", 7 | "No" : "না", 8 | "Save" : "সংরক্ষণ", 9 | "Advanced" : "সুচারু", 10 | "Description" : "বিবরণ" 11 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 12 | } -------------------------------------------------------------------------------- /l10n/ia.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Salveguardante...", 5 | "Saved" : "Salveguardate", 6 | "Host" : "Hospite", 7 | "Port" : "Porto", 8 | "Select" : "Selectionar", 9 | "Save" : "Salveguardar", 10 | "Description" : "Description" 11 | }, 12 | "nplurals=2; plural=(n != 1);"); 13 | -------------------------------------------------------------------------------- /l10n/lb.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "Gespäichert", 3 | "Host" : "Host", 4 | "Port" : "Port", 5 | "Select" : "Select", 6 | "Yes" : "Jo", 7 | "No" : "Nee", 8 | "Save" : "Späicheren", 9 | "Advanced" : "Erweidert", 10 | "Description" : "Beschreiwung" 11 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 12 | } -------------------------------------------------------------------------------- /l10n/nn_NO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "Lagra", 5 | "Host" : "Tenar", 6 | "Port" : "Port", 7 | "Select" : "Vel", 8 | "Delete file" : "Slett fil", 9 | "Save" : "Lagre", 10 | "Advanced" : "Avansert", 11 | "Description" : "Skildring" 12 | }, 13 | "nplurals=2; plural=(n != 1);"); 14 | -------------------------------------------------------------------------------- /l10n/cy_GB.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "Wedi'u cadw", 5 | "Select" : "Select", 6 | "Yes" : "Ie", 7 | "No" : "Na", 8 | "Save" : "Cadw", 9 | "Advanced" : "Uwch", 10 | "Description" : "Disgrifiad" 11 | }, 12 | "nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;"); 13 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2014 ownCloud, Inc. 2 | # SPDX-License-Identifier: AGPL-3.0-only 3 | filter: 4 | excluded_paths: 5 | - '3rdparty/*' 6 | - 'js/jquery*' 7 | - 'l10n/*' 8 | - 'tests/*' 9 | 10 | imports: 11 | - javascript 12 | - php 13 | 14 | tools: 15 | external_code_coverage: true 16 | 17 | -------------------------------------------------------------------------------- /l10n/af.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Bewaar…", 3 | "Saved" : "Bewaar", 4 | "Host" : "Gasheer", 5 | "Port" : "Poort", 6 | "Select" : "Kies", 7 | "Delete file" : "Skrap lêer", 8 | "Save" : "Stoor", 9 | "Advanced" : "Gevorderd", 10 | "Description" : "Beskrywing" 11 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 12 | } -------------------------------------------------------------------------------- /l10n/uz.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Saving…", 3 | "Saved" : "Saved", 4 | "Mode" : "Rejim", 5 | "Port" : "Port", 6 | "Select" : "Select", 7 | "Delete file" : "Delete file", 8 | "Yes" : "Ha", 9 | "No" : "Yo`q", 10 | "Save" : "Saqlash", 11 | "Description" : "Tavsif" 12 | },"pluralForm" :"nplurals=1; plural=0;" 13 | } -------------------------------------------------------------------------------- /l10n/bn_BD.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "সংরক্ষণ করা হলো", 5 | "Host" : "হোস্ট", 6 | "Port" : "পোর্ট", 7 | "Select" : "সিলেক্ট", 8 | "Yes" : "হ্যাঁ", 9 | "No" : "না", 10 | "Save" : "সংরক্ষণ", 11 | "Advanced" : "সুচারু", 12 | "Description" : "বিবরণ" 13 | }, 14 | "nplurals=2; plural=(n != 1);"); 15 | -------------------------------------------------------------------------------- /l10n/lb.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "Gespäichert", 5 | "Host" : "Host", 6 | "Port" : "Port", 7 | "Select" : "Select", 8 | "Yes" : "Jo", 9 | "No" : "Nee", 10 | "Save" : "Späicheren", 11 | "Advanced" : "Erweidert", 12 | "Description" : "Beschreiwung" 13 | }, 14 | "nplurals=2; plural=(n != 1);"); 15 | -------------------------------------------------------------------------------- /l10n/az.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "Saxlanıldı", 3 | "Host" : "Şəbəkədə ünvan", 4 | "Port" : "Port", 5 | "TLS" : "TLS", 6 | "Select" : "Select", 7 | "Yes" : "Bəli", 8 | "No" : "Xeyir", 9 | "Save" : "Saxla", 10 | "Advanced" : "İrəliləmiş", 11 | "Description" : "Açıqlanma" 12 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 13 | } -------------------------------------------------------------------------------- /l10n/km.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "បាន​រក្សាទុក", 3 | "Host" : "ម៉ាស៊ីន​ផ្ទុក", 4 | "Port" : "ច្រក", 5 | "TLS" : "TLS", 6 | "Select" : "Select", 7 | "Yes" : "បាទ ឬចាស", 8 | "No" : "ទេ", 9 | "Save" : "រក្សាទុក", 10 | "Advanced" : "កម្រិត​ខ្ពស់", 11 | "Description" : "ការ​អធិប្បាយ" 12 | },"pluralForm" :"nplurals=1; plural=0;" 13 | } -------------------------------------------------------------------------------- /l10n/mn.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "хадгалж байна", 3 | "Saved" : "Хадгалах", 4 | "Host" : "хост", 5 | "Port" : "порт", 6 | "Select" : "Сонгох", 7 | "Delete file" : "Файл устгах", 8 | "Save" : "Хадгалах", 9 | "Advanced" : "нарийвчилсан", 10 | "Description" : "Тодорхойлолт" 11 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 12 | } -------------------------------------------------------------------------------- /l10n/id.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Menyimpan...", 3 | "Saved" : "Disimpan", 4 | "Host" : "Host", 5 | "Port" : "Port", 6 | "TLS" : "TLS", 7 | "Select" : "Pilih", 8 | "Delete file" : "Hapus berkas", 9 | "Save" : "Simpan", 10 | "Advanced" : "Lanjutan", 11 | "Description" : "Deskrisi" 12 | },"pluralForm" :"nplurals=1; plural=0;" 13 | } -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | lang_map = ja_JP: ja, bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th 4 | 5 | [o:nextcloud:p:nextcloud:r:files_antivirus] 6 | file_filter = translationfiles//files_antivirus.po 7 | source_file = translationfiles/templates/files_antivirus.pot 8 | source_lang = en 9 | type = PO 10 | 11 | -------------------------------------------------------------------------------- /l10n/af.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Bewaar…", 5 | "Saved" : "Bewaar", 6 | "Host" : "Gasheer", 7 | "Port" : "Poort", 8 | "Select" : "Kies", 9 | "Delete file" : "Skrap lêer", 10 | "Save" : "Stoor", 11 | "Advanced" : "Gevorderd", 12 | "Description" : "Beskrywing" 13 | }, 14 | "nplurals=2; plural=(n != 1);"); 15 | -------------------------------------------------------------------------------- /l10n/uz.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Saving…", 5 | "Saved" : "Saved", 6 | "Mode" : "Rejim", 7 | "Port" : "Port", 8 | "Select" : "Select", 9 | "Delete file" : "Delete file", 10 | "Yes" : "Ha", 11 | "No" : "Yo`q", 12 | "Save" : "Saqlash", 13 | "Description" : "Tavsif" 14 | }, 15 | "nplurals=1; plural=0;"); 16 | -------------------------------------------------------------------------------- /tests/data/icap/403-response.txt: -------------------------------------------------------------------------------- 1 | ICAP/1.0 200 OK 2 | ISTag: "b9eb4f031598bb0b-1716440776" 3 | Encapsulated: res-hdr=0, res-body=70 4 | X-Infection-Found: Type=0; Resolution=0; Threat=Eicar; 5 | X-Virus-ID: Testdatei 6 | X-Response-Info: Blocked 7 | X-Response-Description: Durch Löschen gesäubert 8 | 9 | HTTP/1.1 403 Forbidden 10 | Content-Type: text/html 11 | Content-Length: 0 12 | 13 | 0 14 | -------------------------------------------------------------------------------- /l10n/az.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "Saxlanıldı", 5 | "Host" : "Şəbəkədə ünvan", 6 | "Port" : "Port", 7 | "TLS" : "TLS", 8 | "Select" : "Select", 9 | "Yes" : "Bəli", 10 | "No" : "Xeyir", 11 | "Save" : "Saxla", 12 | "Advanced" : "İrəliləmiş", 13 | "Description" : "Açıqlanma" 14 | }, 15 | "nplurals=2; plural=(n != 1);"); 16 | -------------------------------------------------------------------------------- /l10n/ka.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Saving…", 3 | "Saved" : "Saved", 4 | "Host" : "Host", 5 | "Port" : "Port", 6 | "Select" : "Select", 7 | "Delete file" : "Delete file", 8 | "Yes" : "კი", 9 | "No" : "არა", 10 | "Save" : "Save", 11 | "Advanced" : "Advanced", 12 | "Description" : "Description" 13 | },"pluralForm" :"nplurals=2; plural=(n!=1);" 14 | } -------------------------------------------------------------------------------- /l10n/mn.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "хадгалж байна", 5 | "Saved" : "Хадгалах", 6 | "Host" : "хост", 7 | "Port" : "порт", 8 | "Select" : "Сонгох", 9 | "Delete file" : "Файл устгах", 10 | "Save" : "Хадгалах", 11 | "Advanced" : "нарийвчилсан", 12 | "Description" : "Тодорхойлолт" 13 | }, 14 | "nplurals=2; plural=(n != 1);"); 15 | -------------------------------------------------------------------------------- /l10n/bs.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "Spremljeno", 3 | "Port" : "Priključak", 4 | "TLS" : "TLS", 5 | "Select" : "Select", 6 | "Yes" : "Da", 7 | "No" : "Ne", 8 | "Save" : "Spremi", 9 | "Advanced" : "Napredno", 10 | "Description" : "Opis" 11 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" 12 | } -------------------------------------------------------------------------------- /l10n/km.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "បាន​រក្សាទុក", 5 | "Host" : "ម៉ាស៊ីន​ផ្ទុក", 6 | "Port" : "ច្រក", 7 | "TLS" : "TLS", 8 | "Select" : "Select", 9 | "Yes" : "បាទ ឬចាស", 10 | "No" : "ទេ", 11 | "Save" : "រក្សាទុក", 12 | "Advanced" : "កម្រិត​ខ្ពស់", 13 | "Description" : "ការ​អធិប្បាយ" 14 | }, 15 | "nplurals=1; plural=0;"); 16 | -------------------------------------------------------------------------------- /l10n/id.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Menyimpan...", 5 | "Saved" : "Disimpan", 6 | "Host" : "Host", 7 | "Port" : "Port", 8 | "TLS" : "TLS", 9 | "Select" : "Pilih", 10 | "Delete file" : "Hapus berkas", 11 | "Save" : "Simpan", 12 | "Advanced" : "Lanjutan", 13 | "Description" : "Deskrisi" 14 | }, 15 | "nplurals=1; plural=0;"); 16 | -------------------------------------------------------------------------------- /l10n/oc.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Enregistrament…", 3 | "Saved" : "Enregistrat", 4 | "Mode" : "Mòde", 5 | "Host" : "Òste", 6 | "Port" : "Pòrt", 7 | "Select" : "Select", 8 | "Delete file" : "Suprimir fichièr", 9 | "Yes" : "Òc", 10 | "No" : "Non", 11 | "Save" : "Salvar", 12 | "Description" : "Descripcion" 13 | },"pluralForm" :"nplurals=2; plural=(n > 1);" 14 | } -------------------------------------------------------------------------------- /l10n/th.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "บันทึกแล้ว", 3 | "Mode" : "โหมด", 4 | "Host" : "โฮสต์", 5 | "Port" : "พอร์ต", 6 | "TLS" : "TLS", 7 | "Select" : "เลือก", 8 | "Delete file" : "ลบไฟล์", 9 | "Yes" : "ใช่", 10 | "No" : "ไม่ตกลง", 11 | "Save" : "บันทึก", 12 | "Advanced" : "ขั้นสูง", 13 | "Description" : "คำอธิบาย" 14 | },"pluralForm" :"nplurals=1; plural=0;" 15 | } -------------------------------------------------------------------------------- /l10n/vi.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Đang lưu...", 3 | "Saved" : "Đã lưu", 4 | "Mode" : "Chế độ", 5 | "Host" : "Máy chủ", 6 | "Port" : "Cổng", 7 | "Select" : "Chọn", 8 | "Delete file" : "Xóa tệp", 9 | "Yes" : "Có", 10 | "No" : "Không", 11 | "Save" : "Lưu", 12 | "Advanced" : "Nâng cao", 13 | "Description" : "Mô tả" 14 | },"pluralForm" :"nplurals=1; plural=0;" 15 | } -------------------------------------------------------------------------------- /l10n/es_NI.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Guardando...", 3 | "Saved" : "Guardado", 4 | "Host" : "Servidor", 5 | "Port" : "Puerto", 6 | "Select" : "Seleccionar", 7 | "Delete file" : "Borrar archivo", 8 | "Save" : "Guardar", 9 | "Advanced" : "Avanzado", 10 | "Description" : "Descripción" 11 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 12 | } -------------------------------------------------------------------------------- /l10n/es_PA.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Guardando...", 3 | "Saved" : "Guardado", 4 | "Host" : "Servidor", 5 | "Port" : "Puerto", 6 | "Select" : "Seleccionar", 7 | "Delete file" : "Borrar archivo", 8 | "Save" : "Guardar", 9 | "Advanced" : "Avanzado", 10 | "Description" : "Descripción" 11 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 12 | } -------------------------------------------------------------------------------- /l10n/es_PE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Guardando...", 3 | "Saved" : "Guardado", 4 | "Host" : "Servidor", 5 | "Port" : "Puerto", 6 | "Select" : "Seleccionar", 7 | "Delete file" : "Borrar archivo", 8 | "Save" : "Guardar", 9 | "Advanced" : "Avanzado", 10 | "Description" : "Descripción" 11 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 12 | } -------------------------------------------------------------------------------- /l10n/es_PR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Guardando...", 3 | "Saved" : "Guardado", 4 | "Host" : "Servidor", 5 | "Port" : "Puerto", 6 | "Select" : "Seleccionar", 7 | "Delete file" : "Borrar archivo", 8 | "Save" : "Guardar", 9 | "Advanced" : "Avanzado", 10 | "Description" : "Descripción" 11 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 12 | } -------------------------------------------------------------------------------- /l10n/es_PY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Guardando...", 3 | "Saved" : "Guardado", 4 | "Host" : "Servidor", 5 | "Port" : "Puerto", 6 | "Select" : "Seleccionar", 7 | "Delete file" : "Borrar archivo", 8 | "Save" : "Guardar", 9 | "Advanced" : "Avanzado", 10 | "Description" : "Descripción" 11 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 12 | } -------------------------------------------------------------------------------- /l10n/es_UY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Guardando...", 3 | "Saved" : "Guardado", 4 | "Host" : "Servidor", 5 | "Port" : "Puerto", 6 | "Select" : "Seleccionar", 7 | "Delete file" : "Borrar archivo", 8 | "Save" : "Guardar", 9 | "Advanced" : "Avanzado", 10 | "Description" : "Descripción" 11 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 12 | } -------------------------------------------------------------------------------- /img/app.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/shield-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /l10n/ka.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Saving…", 5 | "Saved" : "Saved", 6 | "Host" : "Host", 7 | "Port" : "Port", 8 | "Select" : "Select", 9 | "Delete file" : "Delete file", 10 | "Yes" : "კი", 11 | "No" : "არა", 12 | "Save" : "Save", 13 | "Advanced" : "Advanced", 14 | "Description" : "Description" 15 | }, 16 | "nplurals=2; plural=(n!=1);"); 17 | -------------------------------------------------------------------------------- /l10n/bs.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "Spremljeno", 5 | "Port" : "Priključak", 6 | "TLS" : "TLS", 7 | "Select" : "Select", 8 | "Yes" : "Da", 9 | "No" : "Ne", 10 | "Save" : "Spremi", 11 | "Advanced" : "Napredno", 12 | "Description" : "Opis" 13 | }, 14 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); 15 | -------------------------------------------------------------------------------- /l10n/si.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Antivirus" : "ප්‍රතිවයිරස", 3 | "The file has been removed" : "ගොනුව ඉවත් කර ඇත", 4 | "Antivirus for files" : "ගොනු සඳහා ප්‍රතිවයිරස", 5 | "Antivirus for Files" : "ගොනු සඳහා ප්‍රතිවයිරස", 6 | "Host" : " ධාරකය", 7 | "Select" : "තෝරන්න", 8 | "No" : "නැහැ", 9 | "Save" : "සුරකින්න", 10 | "Description" : "විස්තරය" 11 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 12 | } -------------------------------------------------------------------------------- /img/shield-red.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /l10n/oc.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Enregistrament…", 5 | "Saved" : "Enregistrat", 6 | "Mode" : "Mòde", 7 | "Host" : "Òste", 8 | "Port" : "Pòrt", 9 | "Select" : "Select", 10 | "Delete file" : "Suprimir fichièr", 11 | "Yes" : "Òc", 12 | "No" : "Non", 13 | "Save" : "Salvar", 14 | "Description" : "Descripcion" 15 | }, 16 | "nplurals=2; plural=(n > 1);"); 17 | -------------------------------------------------------------------------------- /img/shield-green.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /l10n/es_419.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Guardando...", 3 | "Saved" : "Guardado", 4 | "Host" : "Servidor", 5 | "Port" : "Puerto", 6 | "Select" : "Seleccionar", 7 | "Delete file" : "Borrar archivo", 8 | "Yes" : "Si", 9 | "Save" : "Guardar", 10 | "Advanced" : "Avanzado", 11 | "Description" : "Descripción" 12 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 13 | } -------------------------------------------------------------------------------- /l10n/th.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "บันทึกแล้ว", 5 | "Mode" : "โหมด", 6 | "Host" : "โฮสต์", 7 | "Port" : "พอร์ต", 8 | "TLS" : "TLS", 9 | "Select" : "เลือก", 10 | "Delete file" : "ลบไฟล์", 11 | "Yes" : "ใช่", 12 | "No" : "ไม่ตกลง", 13 | "Save" : "บันทึก", 14 | "Advanced" : "ขั้นสูง", 15 | "Description" : "คำอธิบาย" 16 | }, 17 | "nplurals=1; plural=0;"); 18 | -------------------------------------------------------------------------------- /l10n/eo.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Konservado...", 3 | "Saved" : "Konservita", 4 | "Host" : "Gastigo", 5 | "Port" : "Pordo", 6 | "TLS" : "TLS", 7 | "Select" : "Elekti", 8 | "Delete file" : "Forigi dosieron", 9 | "Yes" : "Jes", 10 | "No" : "Ne", 11 | "Save" : "Konservi", 12 | "Advanced" : "Progresinta", 13 | "Description" : "Priskribo" 14 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 15 | } -------------------------------------------------------------------------------- /l10n/es_NI.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Guardando...", 5 | "Saved" : "Guardado", 6 | "Host" : "Servidor", 7 | "Port" : "Puerto", 8 | "Select" : "Seleccionar", 9 | "Delete file" : "Borrar archivo", 10 | "Save" : "Guardar", 11 | "Advanced" : "Avanzado", 12 | "Description" : "Descripción" 13 | }, 14 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 15 | -------------------------------------------------------------------------------- /l10n/es_PA.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Guardando...", 5 | "Saved" : "Guardado", 6 | "Host" : "Servidor", 7 | "Port" : "Puerto", 8 | "Select" : "Seleccionar", 9 | "Delete file" : "Borrar archivo", 10 | "Save" : "Guardar", 11 | "Advanced" : "Avanzado", 12 | "Description" : "Descripción" 13 | }, 14 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 15 | -------------------------------------------------------------------------------- /l10n/es_PE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Guardando...", 5 | "Saved" : "Guardado", 6 | "Host" : "Servidor", 7 | "Port" : "Puerto", 8 | "Select" : "Seleccionar", 9 | "Delete file" : "Borrar archivo", 10 | "Save" : "Guardar", 11 | "Advanced" : "Avanzado", 12 | "Description" : "Descripción" 13 | }, 14 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 15 | -------------------------------------------------------------------------------- /l10n/es_PR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Guardando...", 5 | "Saved" : "Guardado", 6 | "Host" : "Servidor", 7 | "Port" : "Puerto", 8 | "Select" : "Seleccionar", 9 | "Delete file" : "Borrar archivo", 10 | "Save" : "Guardar", 11 | "Advanced" : "Avanzado", 12 | "Description" : "Descripción" 13 | }, 14 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 15 | -------------------------------------------------------------------------------- /l10n/es_PY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Guardando...", 5 | "Saved" : "Guardado", 6 | "Host" : "Servidor", 7 | "Port" : "Puerto", 8 | "Select" : "Seleccionar", 9 | "Delete file" : "Borrar archivo", 10 | "Save" : "Guardar", 11 | "Advanced" : "Avanzado", 12 | "Description" : "Descripción" 13 | }, 14 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 15 | -------------------------------------------------------------------------------- /l10n/es_UY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Guardando...", 5 | "Saved" : "Guardado", 6 | "Host" : "Servidor", 7 | "Port" : "Puerto", 8 | "Select" : "Seleccionar", 9 | "Delete file" : "Borrar archivo", 10 | "Save" : "Guardar", 11 | "Advanced" : "Avanzado", 12 | "Description" : "Descripción" 13 | }, 14 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 15 | -------------------------------------------------------------------------------- /l10n/vi.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Đang lưu...", 5 | "Saved" : "Đã lưu", 6 | "Mode" : "Chế độ", 7 | "Host" : "Máy chủ", 8 | "Port" : "Cổng", 9 | "Select" : "Chọn", 10 | "Delete file" : "Xóa tệp", 11 | "Yes" : "Có", 12 | "No" : "Không", 13 | "Save" : "Lưu", 14 | "Advanced" : "Nâng cao", 15 | "Description" : "Mô tả" 16 | }, 17 | "nplurals=1; plural=0;"); 18 | -------------------------------------------------------------------------------- /tests/avirserver.php: -------------------------------------------------------------------------------- 1 | startServer(); 17 | -------------------------------------------------------------------------------- /l10n/si.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Antivirus" : "ප්‍රතිවයිරස", 5 | "The file has been removed" : "ගොනුව ඉවත් කර ඇත", 6 | "Antivirus for files" : "ගොනු සඳහා ප්‍රතිවයිරස", 7 | "Antivirus for Files" : "ගොනු සඳහා ප්‍රතිවයිරස", 8 | "Host" : " ධාරකය", 9 | "Select" : "තෝරන්න", 10 | "No" : "නැහැ", 11 | "Save" : "සුරකින්න", 12 | "Description" : "විස්තරය" 13 | }, 14 | "nplurals=2; plural=(n != 1);"); 15 | -------------------------------------------------------------------------------- /l10n/es_AR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Guardando...", 3 | "Saved" : "Guardado", 4 | "Host" : "Servidor", 5 | "Port" : "Puerto", 6 | "TLS" : "TLS", 7 | "Select" : "Seleccionar", 8 | "Delete file" : "Borrar archivo", 9 | "Yes" : "Sí", 10 | "Save" : "Guardar", 11 | "Advanced" : "Avanzado", 12 | "Description" : "Descripción" 13 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 14 | } -------------------------------------------------------------------------------- /l10n/es_419.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Guardando...", 5 | "Saved" : "Guardado", 6 | "Host" : "Servidor", 7 | "Port" : "Puerto", 8 | "Select" : "Seleccionar", 9 | "Delete file" : "Borrar archivo", 10 | "Yes" : "Si", 11 | "Save" : "Guardar", 12 | "Advanced" : "Avanzado", 13 | "Description" : "Descripción" 14 | }, 15 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 16 | -------------------------------------------------------------------------------- /l10n/eo.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Konservado...", 5 | "Saved" : "Konservita", 6 | "Host" : "Gastigo", 7 | "Port" : "Pordo", 8 | "TLS" : "TLS", 9 | "Select" : "Elekti", 10 | "Delete file" : "Forigi dosieron", 11 | "Yes" : "Jes", 12 | "No" : "Ne", 13 | "Save" : "Konservi", 14 | "Advanced" : "Progresinta", 15 | "Description" : "Priskribo" 16 | }, 17 | "nplurals=2; plural=(n != 1);"); 18 | -------------------------------------------------------------------------------- /l10n/es_AR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Guardando...", 5 | "Saved" : "Guardado", 6 | "Host" : "Servidor", 7 | "Port" : "Puerto", 8 | "TLS" : "TLS", 9 | "Select" : "Seleccionar", 10 | "Delete file" : "Borrar archivo", 11 | "Yes" : "Sí", 12 | "Save" : "Guardar", 13 | "Advanced" : "Avanzado", 14 | "Description" : "Descripción" 15 | }, 16 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 17 | -------------------------------------------------------------------------------- /l10n/ro.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Se salvează...", 3 | "Saved" : "Salvat", 4 | "Mode" : "Mod", 5 | "Host" : "Gazdă", 6 | "Port" : "Portul", 7 | "TLS" : "TLS", 8 | "Select" : "Selectează", 9 | "Delete file" : "Șterge fișier", 10 | "Yes" : "Da", 11 | "No" : "Nu", 12 | "Save" : "Salvează", 13 | "Advanced" : "Avansat", 14 | "Description" : "Descriere" 15 | },"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));" 16 | } -------------------------------------------------------------------------------- /l10n/be.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "Захавана", 3 | "Host" : "Хост", 4 | "Port" : "Порт", 5 | "Select" : "Выбраць", 6 | "Delete file" : "Выдаліць файл", 7 | "Yes" : "Так", 8 | "No" : "Не", 9 | "Save" : "Захаваць", 10 | "Advanced" : "Пашыраныя", 11 | "Description" : "Апісанне" 12 | },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" 13 | } -------------------------------------------------------------------------------- /l10n/mk.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saving…" : "Зачувува ...", 3 | "Saved" : "Зачувано", 4 | "Mode" : "Мод", 5 | "Host" : "Домаќин", 6 | "Port" : "Порта", 7 | "TLS" : "TLS", 8 | "Select" : "Select", 9 | "bytes" : "бајти", 10 | "Delete file" : "Избриши датотека", 11 | "Yes" : "Да", 12 | "No" : "Не", 13 | "Save" : "Зачувај", 14 | "Advanced" : "Напредно", 15 | "Description" : "Опис" 16 | },"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;" 17 | } -------------------------------------------------------------------------------- /l10n/ro.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Se salvează...", 5 | "Saved" : "Salvat", 6 | "Mode" : "Mod", 7 | "Host" : "Gazdă", 8 | "Port" : "Portul", 9 | "TLS" : "TLS", 10 | "Select" : "Selectează", 11 | "Delete file" : "Șterge fișier", 12 | "Yes" : "Da", 13 | "No" : "Nu", 14 | "Save" : "Salvează", 15 | "Advanced" : "Avansat", 16 | "Description" : "Descriere" 17 | }, 18 | "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"); 19 | -------------------------------------------------------------------------------- /l10n/be.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "Захавана", 5 | "Host" : "Хост", 6 | "Port" : "Порт", 7 | "Select" : "Выбраць", 8 | "Delete file" : "Выдаліць файл", 9 | "Yes" : "Так", 10 | "No" : "Не", 11 | "Save" : "Захаваць", 12 | "Advanced" : "Пашыраныя", 13 | "Description" : "Апісанне" 14 | }, 15 | "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); 16 | -------------------------------------------------------------------------------- /l10n/mk.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saving…" : "Зачувува ...", 5 | "Saved" : "Зачувано", 6 | "Mode" : "Мод", 7 | "Host" : "Домаќин", 8 | "Port" : "Порта", 9 | "TLS" : "TLS", 10 | "Select" : "Select", 11 | "bytes" : "бајти", 12 | "Delete file" : "Избриши датотека", 13 | "Yes" : "Да", 14 | "No" : "Не", 15 | "Save" : "Зачувај", 16 | "Advanced" : "Напредно", 17 | "Description" : "Опис" 18 | }, 19 | "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"); 20 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | getFinder() 15 | ->ignoreVCSIgnored(true) 16 | ->notPath('build') 17 | ->notPath('l10n') 18 | ->notPath('lib/Vendor') 19 | ->notPath('src') 20 | ->notPath('vendor') 21 | ->in(__DIR__); 22 | return $config; 23 | -------------------------------------------------------------------------------- /lib/Event/ScanStateEvent.php: -------------------------------------------------------------------------------- 1 | state = $state; 18 | } 19 | 20 | public function getState(): bool { 21 | return $this->state; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/TemporaryHome.php: -------------------------------------------------------------------------------- 1 | 7 | * SPDX-License-Identifier: AGPL-3.0-or-later 8 | */ 9 | 10 | namespace OCA\Files_Antivirus\Tests; 11 | 12 | class TemporaryHome extends \OC\Files\Storage\Temporary { 13 | private string $id; 14 | 15 | public function __construct($arguments = []) { 16 | parent::__construct($arguments); 17 | $this->id = uniqid(); 18 | } 19 | 20 | public function getId(): string { 21 | return 'home::' . $this->id; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lib/Event/BeforeBackgroundScanEvent.php: -------------------------------------------------------------------------------- 1 | file = $file; 19 | } 20 | 21 | public function getFile(): File { 22 | return $this->file; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /l10n/ast.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Unchecked" : "Desmarcóse", 3 | "Saving…" : "Guardando…", 4 | "Antivirus" : "Antivirus", 5 | "The file has been removed" : "Quitóse'l ficheru", 6 | "Saved" : "Guardóse", 7 | "Mode" : "Mou", 8 | "Host" : "Agospiador", 9 | "Port" : "Puertu", 10 | "TLS" : "TLS", 11 | "Select" : "Seleicionar", 12 | "bytes" : "bytes", 13 | "Delete file" : "Desaniciar el ficheru", 14 | "Yes" : "Sí", 15 | "No" : "Non", 16 | "Save" : "Guardar", 17 | "Description" : "Descripción" 18 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 19 | } -------------------------------------------------------------------------------- /l10n/ast.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Unchecked" : "Desmarcóse", 5 | "Saving…" : "Guardando…", 6 | "Antivirus" : "Antivirus", 7 | "The file has been removed" : "Quitóse'l ficheru", 8 | "Saved" : "Guardóse", 9 | "Mode" : "Mou", 10 | "Host" : "Agospiador", 11 | "Port" : "Puertu", 12 | "TLS" : "TLS", 13 | "Select" : "Seleicionar", 14 | "bytes" : "bytes", 15 | "Delete file" : "Desaniciar el ficheru", 16 | "Yes" : "Sí", 17 | "No" : "Non", 18 | "Save" : "Guardar", 19 | "Description" : "Descripción" 20 | }, 21 | "nplurals=2; plural=(n != 1);"); 22 | -------------------------------------------------------------------------------- /templates/notification.php: -------------------------------------------------------------------------------- 1 | 8 |

t('Greetings {user},'))); ?>

9 |

t('Sorry, but a malware was detected in a file you tried to upload and it had to be deleted.')); ?>
10 | t('This email is a notification from {host}. Please, do not reply.'))); ?>

11 |

t('File uploaded: {file}'))); ?>

12 | -------------------------------------------------------------------------------- /l10n/br.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Saved" : "Enrollet", 3 | "Mode" : "Mod", 4 | "Host" : "Ostiz", 5 | "Port" : "Porzh", 6 | "Select" : "Dibab", 7 | "Delete file" : "Dilemel ar restr", 8 | "No" : "Ket", 9 | "Save" : "Enrollañ", 10 | "Advanced" : "Araokadennet", 11 | "Description" : "Diskrivadur" 12 | },"pluralForm" :"nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);" 13 | } -------------------------------------------------------------------------------- /l10n/br.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Saved" : "Enrollet", 5 | "Mode" : "Mod", 6 | "Host" : "Ostiz", 7 | "Port" : "Porzh", 8 | "Select" : "Dibab", 9 | "Delete file" : "Dilemel ar restr", 10 | "No" : "Ket", 11 | "Save" : "Enrollañ", 12 | "Advanced" : "Araokadennet", 13 | "Description" : "Diskrivadur" 14 | }, 15 | "nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);"); 16 | -------------------------------------------------------------------------------- /l10n/pt_PT.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Limpar", 3 | "Saving…" : "A guardar...", 4 | "Saved" : "Guardado", 5 | "Host" : "Anfitrião", 6 | "Address of Antivirus Host." : "Endereço do Anfitrião de Antivírus.", 7 | "Port" : "Porta", 8 | "Port number of Antivirus Host." : "Número da porta do Anfitrião de Antivírus.", 9 | "TLS" : "TLS", 10 | "Select" : "Selecionar", 11 | "bytes" : "bytes", 12 | "Delete file" : "Eliminar ficheiro", 13 | "Yes" : "Sim", 14 | "No" : "Não", 15 | "Save" : "Guardar", 16 | "Advanced" : "Avançado", 17 | "Description" : "Descrição" 18 | },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 19 | } -------------------------------------------------------------------------------- /tests/ICAP/ICAPClientTest.php: -------------------------------------------------------------------------------- 1 | expectException(\RuntimeException::class); 17 | $this->expectExceptionMessageMatches('/Cannot connect to "tcp\:\/\/nothinghere\:8080"\: .*/'); 18 | $icapClient = new ICAPClient('nothinghere', 8080, 2); 19 | $icapClient->respmod('myservice', [], [], []); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /l10n/pt_PT.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Limpar", 5 | "Saving…" : "A guardar...", 6 | "Saved" : "Guardado", 7 | "Host" : "Anfitrião", 8 | "Address of Antivirus Host." : "Endereço do Anfitrião de Antivírus.", 9 | "Port" : "Porta", 10 | "Port number of Antivirus Host." : "Número da porta do Anfitrião de Antivírus.", 11 | "TLS" : "TLS", 12 | "Select" : "Selecionar", 13 | "bytes" : "bytes", 14 | "Delete file" : "Eliminar ficheiro", 15 | "Yes" : "Sim", 16 | "No" : "Não", 17 | "Save" : "Guardar", 18 | "Advanced" : "Avançado", 19 | "Description" : "Descrição" 20 | }, 21 | "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-FileCopyrightText: 2015-2016 ownCloud, Inc. 3 | # SPDX-License-Identifier: AGPL-3.0-only 4 | /build 5 | 6 | # just sane ignores 7 | .*.sw[po] 8 | *.bak 9 | *.BAK 10 | *~ 11 | *.orig 12 | *.class 13 | .cvsignore 14 | Thumbs.db 15 | *.py[co] 16 | _darcs/* 17 | CVS/* 18 | .svn/* 19 | RCS/* 20 | 21 | # kdevelop 22 | .kdev 23 | *.kdev4 24 | 25 | # Lokalize 26 | *lokalize* 27 | 28 | # eclipse 29 | .project 30 | .settings 31 | 32 | # netbeans 33 | nbproject 34 | 35 | # phpStorm 36 | .idea 37 | 38 | # geany 39 | *.geany 40 | 41 | # Cloud9IDE 42 | .settings.xml 43 | 44 | # vim ex mode 45 | .vimrc 46 | 47 | # Mac OS 48 | .DS_Store 49 | 50 | tests/clover.xml 51 | *.cache 52 | vendor 53 | -------------------------------------------------------------------------------- /appinfo/routes.php: -------------------------------------------------------------------------------- 1 | [ 11 | ['name' => 'rule#listAll', 'url' => '/settings/rule/listall', 'verb' => 'GET'], 12 | ['name' => 'rule#clear', 'url' => '/settings/rule/clear', 'verb' => 'POST'], 13 | ['name' => 'rule#reset', 'url' => '/settings/rule/reset', 'verb' => 'POST'], 14 | ['name' => 'rule#save', 'url' => '/settings/rule/save', 'verb' => 'POST'], 15 | ['name' => 'rule#delete', 'url' => '/settings/rule/delete', 'verb' => 'POST'], 16 | ['name' => 'settings#save', 'url' => '/settings/save', 'verb' => 'POST'], 17 | ] 18 | ]; 19 | -------------------------------------------------------------------------------- /lib/Db/Item.php: -------------------------------------------------------------------------------- 1 | jobList = $jobList; 18 | } 19 | 20 | public function getName() { 21 | return 'Cleanup cron task'; 22 | } 23 | 24 | /** 25 | * @return void 26 | */ 27 | public function run(IOutput $output) { 28 | $this->jobList->remove('OCA\Files_Antivirus\Cron\Task'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "platform": { 4 | "php": "8.1" 5 | } 6 | }, 7 | "require-dev": { 8 | "nextcloud/ocp": "dev-master", 9 | "doctrine/dbal": "3.1.4", 10 | "phpunit/phpunit": "^9", 11 | "psalm/phar": "^5.26", 12 | "icewind/streams": "v0.7.5", 13 | "sabre/dav": "^4.2.1", 14 | "nextcloud/coding-standard": "^v1.1.1", 15 | "symfony/event-dispatcher": "4.4.30", 16 | "psr/clock": "^1.0" 17 | }, 18 | "scripts": { 19 | "lint": "find . -name \\*.php -not -path './vendor/*' -not -path './build/*' -not -path './tests/integration/vendor/*' -print0 | xargs -0 -n1 php -l", 20 | "cs:check": "php-cs-fixer fix --dry-run --diff", 21 | "cs:fix": "php-cs-fixer fix", 22 | "psalm": "psalm.phar", 23 | "test:unit": "vendor/bin/phpunit -c tests/phpunit.xml" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | addPsr4('Test\\', OC::$SERVERROOT . '/tests/lib/', true); 23 | \OC::$composerAutoloader->addPsr4('Tests\\', OC::$SERVERROOT . '/tests/', true); 24 | 25 | \OC_Hook::clear(); 26 | \OC_App::loadApp('files_antivirus'); 27 | -------------------------------------------------------------------------------- /lib/StatusFactory.php: -------------------------------------------------------------------------------- 1 | ruleMapper = $ruleMapper; 23 | $this->logger = $logger; 24 | $this->config = $config; 25 | } 26 | 27 | public function newStatus(): Status { 28 | return new Status( 29 | $this->ruleMapper, 30 | $this->logger, 31 | $this->config, 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.github/workflows/package.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: MIT 3 | on: [push, pull_request] 4 | 5 | name: Package 6 | 7 | env: 8 | APP_NAME: files_antivirus 9 | 10 | jobs: 11 | package: 12 | name: Package nightly release 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout code 16 | uses: actions/checkout@v4 17 | - name: Setup krankler 18 | run: | 19 | wget https://github.com/ChristophWurst/krankerl/releases/download/v0.14.0/krankerl 20 | chmod +x krankerl 21 | - name: Package app 22 | run: | 23 | ./krankerl package 24 | - uses: actions/upload-artifact@v4 25 | with: 26 | name: ${{ env.APP_NAME }}.tar.gz 27 | path: build/artifacts/${{ env.APP_NAME }}.tar.gz 28 | -------------------------------------------------------------------------------- /lib/Settings/Admin.php: -------------------------------------------------------------------------------- 1 | config = $config; 18 | } 19 | 20 | public function getForm() { 21 | $data = $this->config->getAllValues(); 22 | return new TemplateResponse('files_antivirus', 'settings', $data, 'blank'); 23 | } 24 | 25 | public function getSection() { 26 | return 'security'; 27 | } 28 | 29 | public function getPriority() { 30 | return 90; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/ICAP/IcapResponseStatus.php: -------------------------------------------------------------------------------- 1 | version = $version; 21 | $this->code = $code; 22 | $this->status = $status; 23 | } 24 | 25 | public function getVersion(): string { 26 | return $this->version; 27 | } 28 | 29 | public function getCode(): int { 30 | return $this->code; 31 | } 32 | 33 | public function getStatus(): string { 34 | return $this->status; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.github/workflows/reuse.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | 6 | # SPDX-FileCopyrightText: 2022 Free Software Foundation Europe e.V. 7 | # 8 | # SPDX-License-Identifier: CC0-1.0 9 | 10 | name: REUSE Compliance Check 11 | 12 | on: [pull_request] 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | reuse-compliance-check: 19 | runs-on: ubuntu-latest-low 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 23 | with: 24 | persist-credentials: false 25 | 26 | - name: REUSE Compliance Check 27 | uses: fsfe/reuse-action@bb774aa972c2a89ff34781233d275075cbddf542 # v5.0.0 28 | -------------------------------------------------------------------------------- /tests/ICAP/ResponseParserTest.php: -------------------------------------------------------------------------------- 1 | read_response(fopen($responsePath, 'r')); 17 | } 18 | 19 | public function testParse403() { 20 | $response = $this->parseResponse(__DIR__ . '/../data/icap/403-response.txt'); 21 | $this->assertEquals('HTTP/1.1 403 Forbidden', $response->getResponseHeaders()['HTTP_STATUS']); 22 | } 23 | 24 | public function testParseNullBody() { 25 | $response = $this->parseResponse(__DIR__ . '/../data/icap/null-body.txt'); 26 | $this->assertEquals([], $response->getResponseHeaders()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/ICAP/IcapResponse.php: -------------------------------------------------------------------------------- 1 | status = $status; 25 | $this->headers = $headers; 26 | $this->responseHeaders = $responseHeaders; 27 | } 28 | 29 | public function getStatus(): IcapResponseStatus { 30 | return $this->status; 31 | } 32 | 33 | public function getIcapHeaders(): array { 34 | return $this->headers; 35 | } 36 | 37 | public function getResponseHeaders(): array { 38 | return $this->responseHeaders; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/Migration/Version60100Date20250424072838.php: -------------------------------------------------------------------------------- 1 | getTable('files_antivirus'); 30 | if ($filesAntivirusTable->hasColumn('etag')) { 31 | $filesAntivirusTable->dropColumn('etag'); 32 | } 33 | 34 | return $schema; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/Activity/Setting.php: -------------------------------------------------------------------------------- 1 | l = $l; 17 | } 18 | 19 | public function getIdentifier() { 20 | return Provider::TYPE_VIRUS_DETECTED; 21 | } 22 | 23 | public function getName() { 24 | return $this->l->t('Antivirus detected a virus'); 25 | } 26 | 27 | public function getPriority() { 28 | return 70; 29 | } 30 | 31 | public function canChangeStream() { 32 | return false; 33 | } 34 | 35 | public function isDefaultEnabledStream() { 36 | return true; 37 | } 38 | 39 | public function canChangeMail() { 40 | return false; 41 | } 42 | 43 | public function isDefaultEnabledMail() { 44 | return false; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/Migration/Install.php: -------------------------------------------------------------------------------- 1 | ruleMapper = $ruleMapper; 22 | $this->config = $config; 23 | } 24 | 25 | public function getName() { 26 | return 'Populare default rules'; 27 | } 28 | 29 | /** 30 | * @return void 31 | */ 32 | public function run(IOutput $output) { 33 | $rules = $this->ruleMapper->findAll(); 34 | 35 | if ($rules === []) { 36 | $this->ruleMapper->populate(); 37 | } 38 | 39 | $this->config->setAppValue('files_antivirus', 'av_path', '/usr/bin/clamscan'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/Scanner/ScannerBaseTest.php: -------------------------------------------------------------------------------- 1 | getScanner(); 20 | $status = $scanner->scanString('foo'); 21 | $this->assertEquals($status->getNumericStatus(), Status::SCANRESULT_CLEAN); 22 | } 23 | public function testScanEicar() { 24 | $eicar = base64_decode(str_rot13('JQICVINyDRSDJmEpHScLAGDbHS4cA0AQXGq9WRIWD0SFYIAHDH5RDIWRYHSBIRyJFIWIHl1HEIAHYHMWGRHuWRteFPb=')); 25 | $scanner = $this->getScanner(); 26 | $status = $scanner->scanString($eicar); 27 | $this->assertEquals($status->getNumericStatus(), Status::SCANRESULT_INFECTED); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/Activity/Filter.php: -------------------------------------------------------------------------------- 1 | l = $l; 21 | $this->url = $url; 22 | } 23 | 24 | public function getIdentifier() { 25 | return 'files_antivirus'; 26 | } 27 | 28 | public function getName() { 29 | return $this->l->t('Antivirus'); 30 | } 31 | 32 | public function getPriority() { 33 | return 70; 34 | } 35 | 36 | public function getIcon() { 37 | return $this->url->imagePath('files_antivirus', 'shield-dark.svg'); 38 | } 39 | 40 | public function filterTypes(array $types) { 41 | return $types; 42 | } 43 | 44 | public function allowedApps() { 45 | return ['files_antivirus']; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 14 | 15 | . 16 | 17 | 18 | 19 | 20 | ../../files_antivirus 21 | 22 | ../../files_antivirus/l10n 23 | ../../files_antivirus/tests 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /.github/workflows/fixup.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Block fixup and squash commits 10 | 11 | on: 12 | pull_request: 13 | types: [opened, ready_for_review, reopened, synchronize] 14 | 15 | permissions: 16 | contents: read 17 | 18 | concurrency: 19 | group: fixup-${{ github.head_ref || github.run_id }} 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | commit-message-check: 24 | if: github.event.pull_request.draft == false 25 | 26 | permissions: 27 | pull-requests: write 28 | name: Block fixup and squash commits 29 | 30 | runs-on: ubuntu-latest-low 31 | 32 | steps: 33 | - name: Run check 34 | uses: skjnldsv/block-fixup-merge-action@42d26e1b536ce61e5cf467d65fb76caf4aa85acf # v1 35 | with: 36 | repo-token: ${{ secrets.GITHUB_TOKEN }} 37 | -------------------------------------------------------------------------------- /l10n/sq.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Pastro", 3 | "Infected" : "Infektuar", 4 | "Scanner output" : "Prodhim i skanerit", 5 | "Saving…" : "Duke u ruajtur...", 6 | "Antivirus" : "Antivirus", 7 | "File {file} is infected with {virus}" : "Skedari {file} është infektuar me {virus}", 8 | "The file has been removed" : "Skedari është fshirë", 9 | "Saved" : "Ruajtur", 10 | "Host" : "Strehë", 11 | "Port" : "Porta", 12 | "TLS" : "TLS", 13 | "Select" : "Zgjidhni", 14 | "Not required in Daemon Mode." : "Nuk kërkohet në Gjendjen Daemon", 15 | "When infected files are found during a background scan" : "Kur skedarë të infektuar gjenden gjatë skanimit ", 16 | "Only log" : "Vetëm log", 17 | "Delete file" : "Fshi skedarin", 18 | "Yes" : "Po", 19 | "Save" : "Ruaj", 20 | "Advanced" : "Të avancuara", 21 | "Rules" : "Rregulla", 22 | "Clear All" : "Fshi të gjitha", 23 | "Reset to defaults" : "Rivendosi te gjendja e paracaktuar", 24 | "Description" : "Përshkrim", 25 | "Mark as" : "Shëno si", 26 | "Add a rule" : "Shto një rregull" 27 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 28 | } -------------------------------------------------------------------------------- /l10n/sq.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Pastro", 5 | "Infected" : "Infektuar", 6 | "Scanner output" : "Prodhim i skanerit", 7 | "Saving…" : "Duke u ruajtur...", 8 | "Antivirus" : "Antivirus", 9 | "File {file} is infected with {virus}" : "Skedari {file} është infektuar me {virus}", 10 | "The file has been removed" : "Skedari është fshirë", 11 | "Saved" : "Ruajtur", 12 | "Host" : "Strehë", 13 | "Port" : "Porta", 14 | "TLS" : "TLS", 15 | "Select" : "Zgjidhni", 16 | "Not required in Daemon Mode." : "Nuk kërkohet në Gjendjen Daemon", 17 | "When infected files are found during a background scan" : "Kur skedarë të infektuar gjenden gjatë skanimit ", 18 | "Only log" : "Vetëm log", 19 | "Delete file" : "Fshi skedarin", 20 | "Yes" : "Po", 21 | "Save" : "Ruaj", 22 | "Advanced" : "Të avancuara", 23 | "Rules" : "Rregulla", 24 | "Clear All" : "Fshi të gjitha", 25 | "Reset to defaults" : "Rivendosi te gjendja e paracaktuar", 26 | "Description" : "Përshkrim", 27 | "Mark as" : "Shëno si", 28 | "Add a rule" : "Shto një rregull" 29 | }, 30 | "nplurals=2; plural=(n != 1);"); 31 | -------------------------------------------------------------------------------- /tests/Db/RuleTest.php: -------------------------------------------------------------------------------- 1 | 0, 22 | 'statusType' => Rule::RULE_TYPE_CODE, 23 | 'result' => 0, 24 | 'match' => '', 25 | 'description' => '', 26 | 'status' => Status::SCANRESULT_CLEAN 27 | ]; 28 | $expected = [ 29 | 'group_id' => 0, 30 | 'status_type' => Rule::RULE_TYPE_CODE, 31 | 'result' => 0, 32 | 'match' => '', 33 | 'description' => '', 34 | 'status' => Status::SCANRESULT_CLEAN 35 | ]; 36 | 37 | $rule = Rule::fromParams($data); 38 | $actual = $rule->jsonSerialize(); 39 | $this->assertArrayHasKey('id', $actual); 40 | unset($actual['id']); 41 | $this->assertEquals( 42 | $expected, 43 | $actual 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /.github/workflows/lint-info-xml.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint info.xml 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-info-xml-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | xml-linters: 22 | runs-on: ubuntu-latest-low 23 | 24 | name: info.xml lint 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 28 | 29 | - name: Download schema 30 | run: wget https://raw.githubusercontent.com/nextcloud/appstore/master/nextcloudappstore/api/v1/release/info.xsd 31 | 32 | - name: Lint info.xml 33 | uses: ChristophWurst/xmllint-action@36f2a302f84f8c83fceea0b9c59e1eb4a616d3c1 # v1.2 34 | with: 35 | xml-file: ./appinfo/info.xml 36 | xml-schema-file: ./info.xsd 37 | -------------------------------------------------------------------------------- /tests/Db/ItemMapperTest.php: -------------------------------------------------------------------------------- 1 | itemMapper = new ItemMapper(\OC::$server->get(IDBConnection::class)); 27 | } 28 | 29 | public function testGetNonExisting() { 30 | $this->expectException(DoesNotExistException::class); 31 | $this->itemMapper->findByFileId(999); 32 | } 33 | 34 | public function testInsertGetDelete() { 35 | $item = new Item(); 36 | $item->setFileid(1); 37 | $item->setCheckTime(123); 38 | 39 | $this->itemMapper->insert($item); 40 | 41 | $retrievedItem = $this->itemMapper->findByFileId(1); 42 | $this->assertEquals(123, $retrievedItem->getCheckTime()); 43 | 44 | $this->itemMapper->findByFileId(1); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/Scanner/IScanner.php: -------------------------------------------------------------------------------- 1 | 2 | 6 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/Scanner/ScannerFactoryTest.php: -------------------------------------------------------------------------------- 1 | config = $this->createMock(IConfig::class); 29 | $this->config->method('getAppValue') 30 | ->with('files_antivirus', 'av_mode', 'executable') 31 | ->willReturn('daemon'); 32 | 33 | $this->appConfig = new AppConfig($this->config); 34 | 35 | $this->request = $this->createMock(IRequest::class); 36 | 37 | $this->scannerFactory = new ScannerFactory( 38 | $this->appConfig, 39 | \OC::$server, 40 | $this->request, 41 | ); 42 | } 43 | 44 | public function testGetScanner() { 45 | $instanceA = $this->scannerFactory->getScanner('/dev/null'); 46 | $instanceB = $this->scannerFactory->getScanner('/dev/null'); 47 | 48 | $this->assertNotSame($instanceA, $instanceB); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /tests/Scanner/ExternalKasperskyTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Set KASPERSKY_HOST and KASPERSKY_PORT to enable kaspersky tests'); 25 | } 26 | 27 | $logger = $this->createMock(LoggerInterface::class); 28 | $config = $this->createPartialMock(AppConfig::class, ['getAppValue']); 29 | $config->method('getAppValue') 30 | ->willReturnCallback(function ($key) { 31 | switch ($key) { 32 | case 'av_host': 33 | return getenv('KASPERSKY_HOST'); 34 | case 'av_port': 35 | return getenv('KASPERSKY_PORT'); 36 | case 'av_scan_first_bytes': 37 | return '-1'; 38 | default: 39 | return ''; 40 | } 41 | }); 42 | return new ExternalKaspersky($config, $logger, \OC::$server->get(StatusFactory::class), \OC::$server->get(IClientService::class)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /REUSE.toml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | version = 1 4 | SPDX-PackageName = "files_antivirus" 5 | SPDX-PackageSupplier = "Nextcloud " 6 | SPDX-PackageDownloadLocation = "https://github.com/nextcloud/files_antivirus" 7 | 8 | [[annotations]] 9 | path = ["l10n/**.js", "l10n/**.json"] 10 | precedence = "aggregate" 11 | SPDX-FileCopyrightText = "2013-2016 ownCloud Inc., 2016-2024 Nextcloud GmbH and Nextcloud contributors" 12 | SPDX-License-Identifier = "AGPL-3.0-or-later" 13 | 14 | [[annotations]] 15 | path = [".envrc", "Cargo.lock", "composer.json", "composer.lock", "tests/stub.phpstub"] 16 | precedence = "aggregate" 17 | SPDX-FileCopyrightText = "2021 Nextcloud GmbH and Nextcloud contributors" 18 | SPDX-License-Identifier = "AGPL-3.0-or-later" 19 | 20 | [[annotations]] 21 | path = [".tx/config"] 22 | precedence = "aggregate" 23 | SPDX-FileCopyrightText = "2018 Nextcloud GmbH and Nextcloud contributors" 24 | SPDX-License-Identifier = "AGPL-3.0-or-later" 25 | 26 | [[annotations]] 27 | path = ["flake.lock", "flake.nix"] 28 | precedence = "aggregate" 29 | SPDX-FileCopyrightText = "2023 Nextcloud GmbH and Nextcloud contributors" 30 | SPDX-License-Identifier = "AGPL-3.0-or-later" 31 | 32 | [[annotations]] 33 | path = ["img/app.png", "img/app.svg", "img/shield-dark.svg", "img/shield-green.svg", "img/shield-red.svg"] 34 | precedence = "aggregate" 35 | SPDX-FileCopyrightText = "2018-2024 Google LLC" 36 | SPDX-License-Identifier = "Apache-2.0" 37 | -------------------------------------------------------------------------------- /lib/ItemFactory.php: -------------------------------------------------------------------------------- 1 | config = $appConfig; 37 | $this->activityManager = $activityManager; 38 | $this->itemMapper = $itemMapper; 39 | $this->logger = $logger; 40 | $this->rootFolder = $rootFolder; 41 | $this->appManager = $appManager; 42 | $this->clock = $clock; 43 | } 44 | 45 | public function newItem(File $file, bool $isCron = false): Item { 46 | return new Item( 47 | $this->config, 48 | $this->activityManager, 49 | $this->itemMapper, 50 | $this->logger, 51 | $this->rootFolder, 52 | $this->appManager, 53 | $file, 54 | $this->clock, 55 | $isCron 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/ICAP/ICAPTlsClient.php: -------------------------------------------------------------------------------- 1 | certificateManager = $certificateManager; 27 | $this->verifyTlsPeer = $verifyTlsPeer; 28 | } 29 | 30 | /** 31 | * Connect to ICAP server 32 | * 33 | * @return resource 34 | */ 35 | protected function connect() { 36 | $ctx = stream_context_create([ 37 | 'ssl' => [ 38 | 'verify_peer' => $this->verifyTlsPeer, 39 | 'verify_peer_name' => $this->verifyTlsPeer, 40 | 'allow_self_signed' => !$this->verifyTlsPeer, 41 | 'cafile' => $this->certificateManager->getAbsoluteBundlePath() 42 | ], 43 | ]); 44 | $stream = \stream_socket_client( 45 | "tls://{$this->host}:{$this->port}", 46 | $errorCode, 47 | $errorMessage, 48 | $this->connectTimeout, 49 | STREAM_CLIENT_CONNECT, 50 | $ctx 51 | ); 52 | 53 | if (!$stream) { 54 | throw new RuntimeException( 55 | "Cannot connect to \"tls://{$this->host}:{$this->port}\": $errorMessage (code $errorCode)" 56 | ); 57 | } 58 | 59 | return $stream; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/Sabre/PropfindPlugin.php: -------------------------------------------------------------------------------- 1 | appConfig = $appConfig; 29 | $this->eventDispatcher = $eventDispatcher; 30 | } 31 | 32 | /** 33 | * @return void 34 | */ 35 | public function initialize(Server $server) { 36 | $server->on('beforeMove', [$this, 'beforeMove'], 90); 37 | $this->server = $server; 38 | } 39 | 40 | /** 41 | * @param string $sourcePath source path 42 | * @param string $destination destination path 43 | * 44 | * @return void 45 | */ 46 | public function beforeMove($sourcePath, $destination) { 47 | $sourceNode = $this->server->tree->getNodeForPath($sourcePath); 48 | if (!$sourceNode instanceof FutureFile) { 49 | // skip handling as the source is not a chunked FutureFile 50 | return; 51 | } 52 | 53 | $avMaxFileSize = $this->appConfig->getAvMaxFileSize(); 54 | if ($avMaxFileSize > -1 && $sourceNode->getSize() > $avMaxFileSize) { 55 | $this->eventDispatcher->dispatchTyped( 56 | new ScanStateEvent(false) 57 | ); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /.github/workflows/lint-php-cs.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint php-cs 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-php-cs-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | lint: 22 | runs-on: ubuntu-latest 23 | 24 | name: php-cs 25 | 26 | steps: 27 | - name: Checkout 28 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 29 | 30 | - name: Get php version 31 | id: versions 32 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1 33 | 34 | - name: Set up php${{ steps.versions.outputs.php-min }} 35 | uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2 36 | with: 37 | php-version: ${{ steps.versions.outputs.php-min }} 38 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite 39 | coverage: none 40 | ini-file: development 41 | env: 42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 43 | 44 | - name: Install dependencies 45 | run: composer i 46 | 47 | - name: Lint 48 | run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 ) 49 | -------------------------------------------------------------------------------- /.github/workflows/phpunit-summary-when-unrelated.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: PHPUnit summary 10 | 11 | on: 12 | pull_request: 13 | paths-ignore: 14 | - '.github/workflows/**' 15 | - 'appinfo/**' 16 | - 'lib/**' 17 | - 'templates/**' 18 | - 'tests/**' 19 | - 'vendor/**' 20 | - 'vendor-bin/**' 21 | - '.php-cs-fixer.dist.php' 22 | - 'composer.json' 23 | - 'composer.lock' 24 | 25 | permissions: 26 | contents: read 27 | 28 | jobs: 29 | summary-mysql: 30 | permissions: 31 | contents: none 32 | runs-on: ubuntu-latest 33 | 34 | name: phpunit-mysql-summary 35 | 36 | steps: 37 | - name: Summary status 38 | run: 'echo "No PHP files changed, skipped PHPUnit"' 39 | 40 | summary-oci: 41 | permissions: 42 | contents: none 43 | runs-on: ubuntu-latest 44 | 45 | name: phpunit-oci-summary 46 | 47 | steps: 48 | - name: Summary status 49 | run: 'echo "No PHP files changed, skipped PHPUnit"' 50 | 51 | summary-pgsql: 52 | permissions: 53 | contents: none 54 | runs-on: ubuntu-latest 55 | 56 | name: phpunit-pgsql-summary 57 | 58 | steps: 59 | - name: Summary status 60 | run: 'echo "No PHP files changed, skipped PHPUnit"' 61 | 62 | summary-sqlite: 63 | permissions: 64 | contents: none 65 | runs-on: ubuntu-latest 66 | 67 | name: phpunit-sqlite-summary 68 | 69 | steps: 70 | - name: Summary status 71 | run: 'echo "No PHP files changed, skipped PHPUnit"' 72 | -------------------------------------------------------------------------------- /lib/Scanner/ScannerFactory.php: -------------------------------------------------------------------------------- 1 | appConfig = $appConfig; 25 | $this->serverContainer = $serverContainer; 26 | $this->request = $request; 27 | } 28 | 29 | /** 30 | * Produce a scanner instance 31 | * 32 | * @return IScanner 33 | */ 34 | public function getScanner(?string $path) { 35 | $avMode = $this->appConfig->getAvMode(); 36 | switch ($avMode) { 37 | case 'daemon': 38 | case 'socket': 39 | $scannerClass = ExternalClam::class; 40 | break; 41 | case 'executable': 42 | $scannerClass = LocalClam::class; 43 | break; 44 | case 'kaspersky': 45 | $scannerClass = ExternalKaspersky::class; 46 | break; 47 | case 'icap': 48 | $scannerClass = ICAP::class; 49 | break; 50 | default: 51 | throw new \InvalidArgumentException('Application is misconfigured. Please check the settings at the admin page. Invalid mode: ' . $avMode); 52 | } 53 | 54 | /** @var ScannerBase $scanner */ 55 | $scanner = $this->serverContainer->get($scannerClass); 56 | if ($path !== null) { 57 | $scanner->setPath($path); 58 | } 59 | if ($this->request->getRemoteAddress()) { 60 | $scanner->setRequest($this->request); 61 | } 62 | return $scanner; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/CallbackReadDataWrapper.php: -------------------------------------------------------------------------------- 1 | [ 33 | 'source' => $source, 34 | 'readData' => $read, 35 | 'write' => $write, 36 | 'close' => $close, 37 | 'readDir' => $readDir, 38 | 'preClose' => $preClose 39 | ] 40 | ]); 41 | return Wrapper::wrapSource($source, $context, 'callbackReadData', self::class); 42 | } 43 | 44 | /** 45 | * @return true 46 | */ 47 | protected function open() { 48 | $context = $this->loadContext('callbackReadData'); 49 | 50 | $this->readDataCallback = $context['readData']; 51 | $this->writeCallback = $context['write']; 52 | $this->closeCallback = $context['close']; 53 | $this->readDirCallBack = $context['readDir']; 54 | return true; 55 | } 56 | 57 | public function stream_read($count) { 58 | $result = parent::stream_read($count); 59 | if (is_callable($this->readDataCallback)) { 60 | call_user_func($this->readDataCallback, strlen($result), $result); 61 | } 62 | return $result; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /.github/contributing.md: -------------------------------------------------------------------------------- 1 | 5 | ## Submitting issues 6 | 7 | If you have questions about how to install or use Nextcloud, please direct these to our [forum][forum]. We are also available on [IRC][irc]. 8 | 9 | ### Short version 10 | 11 | * The [**issue template can be found here**][template]. Please always use the issue template when reporting issues. 12 | 13 | ### Guidelines 14 | * Please search the existing issues first, it's likely that your issue was already reported or even fixed. 15 | - Go to one of the repositories, click "issues" and type any word in the top search/command bar. 16 | - You can also filter by appending e. g. "state:open" to the search string. 17 | - More info on [search syntax within github](https://help.github.com/articles/searching-issues) 18 | * This repository ([Antivirus](https://github.com/nextcloud/files_antivirus/issues)) is *only* for issues within the Antivirus code. 19 | * __SECURITY__: Report any potential security bug to us via [our HackerOne page](https://hackerone.com/nextcloud) or security@nextcloud.com following our [security policy](https://nextcloud.com/security/) instead of filing an issue in our bug tracker 20 | * Report the issue using our [template][template], it includes all the information we need to track down the issue. 21 | 22 | Help us to maximize the effort we can spend fixing issues and adding new features, by not reporting duplicate issues. 23 | 24 | [template]: https://raw.github.com/nextcloud/files_antivirus/master/.github/issue_template.md 25 | [forum]: https://help.nextcloud.com/ 26 | [irc]: https://webchat.freenode.net/?channels=nextcloud 27 | 28 | ### Contribute Code and translations 29 | Please check [server's contribution guidelines](https://github.com/nextcloud/server/blob/master/CONTRIBUTING.md#contributing-to-source-code) for further information about contributing code and translations. 30 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 8 | ### Steps to reproduce 9 | 1. 10 | 2. 11 | 3. 12 | 13 | ### Expected behaviour 14 | Tell us what should happen 15 | 16 | ### Actual behaviour 17 | Tell us what happens instead 18 | 19 | ### Server configuration 20 | 23 | 24 | **Operating system**: 25 | 26 | **Web server:** 27 | 28 | **Database:** 29 | 30 | **PHP version:** 31 | 32 | **Nextcloud version:** (see Nextcloud admin page) 33 | 34 | **Where did you install Nextcloud from:** 35 | 36 | 37 | **List of activated apps:** 38 | 39 | ``` 40 | If you have access to your command line run e.g.: 41 | sudo -u www-data php occ app:list 42 | from within your Nextcloud installation folder 43 | ``` 44 | 45 | **Nextcloud configuration:** 46 | 47 | ``` 48 | If you have access to your command line run e.g.: 49 | sudo -u www-data php occ config:list system 50 | from within your Nextcloud installation folder 51 | 52 | or 53 | 54 | Insert your config.php content here 55 | Make sure to remove all sensitive content such as passwords. (e.g. database password, passwordsalt, secret, smtp password, …) 56 | ``` 57 | 58 | ### Client configuration 59 | **Browser:** 60 | 61 | **Operating system:** 62 | 63 | ### Logs 64 | 65 | #### Nextcloud log (data/owncloud.log) 66 | ``` 67 | Insert your Nextcloud log here 68 | ``` 69 | 70 | #### Browser log 71 | ``` 72 | Insert your browser log here, this could for example include: 73 | 74 | a) The javascript console log 75 | b) The network log 76 | c) ... 77 | ``` 78 | -------------------------------------------------------------------------------- /tests/Scanner/ICAPTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Set ICAP_HOST, ICAP_PORT, ICAP_REQUEST, ICAP_MODE and ICAP_HEADER to enable icap tests'); 25 | } 26 | 27 | $logger = $this->createMock(LoggerInterface::class); 28 | $config = $this->createPartialMock(AppConfig::class, ['getAppValue', 'getAvIcapTls']); 29 | $config->method('getAppValue') 30 | ->willReturnCallback(function ($key) { 31 | switch ($key) { 32 | case 'av_host': 33 | return getenv('ICAP_HOST'); 34 | case 'av_port': 35 | return getenv('ICAP_PORT'); 36 | case 'av_icap_request_service': 37 | return getenv('ICAP_REQUEST'); 38 | case 'av_icap_response_header': 39 | return getenv('ICAP_HEADER'); 40 | case 'av_icap_mode': 41 | return getenv('ICAP_MODE'); 42 | case 'av_stream_max_length': 43 | return '26214400'; 44 | case 'av_icap_chunk_size': 45 | return '1048576'; 46 | case 'av_icap_connect_timeout': 47 | return '5'; 48 | case 'av_scan_first_bytes': 49 | return '-1'; 50 | default: 51 | return ''; 52 | } 53 | }); 54 | $config->method('getAvIcapTls') 55 | ->willReturn(getenv('ICAP_TRANSPORT') === 'tls'); 56 | return new ICAP($config, $logger, \OC::$server->get(StatusFactory::class), \OC::$server->get(ICertificateManager::class), false); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/Scanner/LocalClam.php: -------------------------------------------------------------------------------- 1 | avPath = escapeshellcmd($this->appConfig->getAvPath()); 35 | 36 | // check that the executable is available 37 | if (!file_exists($this->avPath)) { 38 | throw new \RuntimeException('The antivirus executable could not be found at ' . $this->avPath); 39 | } 40 | } 41 | 42 | /** 43 | * @return void 44 | */ 45 | public function initScanner() { 46 | parent::initScanner(); 47 | 48 | // using 2>&1 to grab the full command-line output. 49 | $cmd = $this->avPath . ' ' . $this->appConfig->getCmdline() . ' - 2>&1'; 50 | $descriptorSpec = [ 51 | 0 => ['pipe', 'r'], // STDIN 52 | 1 => ['pipe', 'w'] // STDOUT 53 | ]; 54 | 55 | $this->process = proc_open($cmd, $descriptorSpec, $this->pipes); 56 | if (!is_resource($this->process)) { 57 | throw new \RuntimeException('Error starting process'); 58 | } 59 | $this->writeHandle = $this->pipes[0]; 60 | } 61 | 62 | /** 63 | * @return void 64 | */ 65 | protected function shutdownScanner() { 66 | @fclose($this->pipes[0]); 67 | $output = stream_get_contents($this->pipes[1]); 68 | @fclose($this->pipes[1]); 69 | 70 | $result = proc_close($this->process); 71 | $this->logger->debug( 72 | 'Exit code :: ' . $result . ' Response :: ' . $output, 73 | ['app' => 'files_antivirus'] 74 | ); 75 | $this->status->parseResponse($output, $result); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /.github/workflows/lint-php.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint php 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-php-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | matrix: 22 | runs-on: ubuntu-latest-low 23 | outputs: 24 | php-versions: ${{ steps.versions.outputs.php-versions }} 25 | steps: 26 | - name: Checkout app 27 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 28 | - name: Get version matrix 29 | id: versions 30 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.0.0 31 | 32 | php-lint: 33 | runs-on: ubuntu-latest 34 | needs: matrix 35 | strategy: 36 | matrix: 37 | php-versions: ${{fromJson(needs.matrix.outputs.php-versions)}} 38 | 39 | name: php-lint 40 | 41 | steps: 42 | - name: Checkout 43 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 44 | 45 | - name: Set up php ${{ matrix.php-versions }} 46 | uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2 47 | with: 48 | php-version: ${{ matrix.php-versions }} 49 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite 50 | coverage: none 51 | ini-file: development 52 | env: 53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 54 | 55 | - name: Lint 56 | run: composer run lint 57 | 58 | summary: 59 | permissions: 60 | contents: none 61 | runs-on: ubuntu-latest-low 62 | needs: php-lint 63 | 64 | if: always() 65 | 66 | name: php-lint-summary 67 | 68 | steps: 69 | - name: Summary status 70 | run: if ${{ needs.php-lint.result != 'success' && needs.php-lint.result != 'skipped' }}; then exit 1; fi 71 | -------------------------------------------------------------------------------- /l10n/ka_GE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "გასუფთავება", 3 | "Infected" : "დაზიანებულია", 4 | "Unchecked" : "შეუმოწმებელია", 5 | "Scanner exit status" : "სკანერის გათიშვის სტატუსი", 6 | "Scanner output" : "სკანერის გამოცემა", 7 | "Saving…" : "მიმდინარეობს დამახსოვრება...", 8 | "Antivirus" : "ანტივირუსი", 9 | "Virus %s is detected in the file. Upload cannot be completed." : "ფაილში აღმოჩენილია ვირუსი %s. ატვირთვა ვერ დასრულდება.", 10 | "Saved" : "შენახულია", 11 | "Greetings {user}," : "გამარჯობა {user},", 12 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "ბოდიში, მაგრამ ფაილში, რომლის ატვირთვაც სცადეთ, აღმოჩნდა ვირუსი და გაუქმდა.", 13 | "This email is a notification from {host}. Please, do not reply." : "ეს ელ-ფოსტა შეტყობინებაა ჰოსტიდან {host}. გთხოვთ ნუ უპასუხებთ.", 14 | "File uploaded: {file}" : "ფაილი აიტვირთა: {file}", 15 | "Mode" : "რეჟიმი", 16 | "Socket" : "სოკეტი", 17 | "Not required in Executable Mode." : "შესრულებად რეჟიმში არაა აუცილებელი.", 18 | "Host" : "ჰოსტი", 19 | "Address of Antivirus Host." : "ანტივირუსის ჰოსტის მისამართი.", 20 | "Port" : "პორტი", 21 | "Port number of Antivirus Host." : "ანტივირუსის ჰოსტის პორტის ნომერი.", 22 | "Select" : "არჩევა", 23 | "Stream Length" : "სტრიმის სიგრძე", 24 | "ClamAV StreamMaxLength value in bytes." : "ClamAV StreamMaxLength მნიშვნელობა ბაიტებში.", 25 | "bytes" : "ბაიტები", 26 | "Path to clamscan" : "clamscan მისამართი", 27 | "Path to clamscan executable." : "clamscan შესრულებადის მისამართი.", 28 | "Not required in Daemon Mode." : "Daemon რეჟიმში არაა აუცილებელი.", 29 | "Extra command line options (comma-separated)" : "ექსტრა კონსოლის პარამეტრი (გამოყოფილი-მძიმით)", 30 | "Only log" : "მხოლოდ ჩაიწეროს ლოგი", 31 | "Delete file" : "გაუქმდეს ფაილი", 32 | "Yes" : "დიახ", 33 | "Save" : "შენახვა", 34 | "Advanced" : "მოწინავე", 35 | "Rules" : "წესები", 36 | "Clear All" : "ყველას გასუფთავება", 37 | "Reset to defaults" : "საწყის რეჟიმზე დაბრუნება", 38 | "Match by" : "დამთხვევა", 39 | "Scanner exit status or signature to search" : "სკანერის გათიშვის სტატუსი ან ხელმოწერები ძიებისთვის", 40 | "Description" : "აღწერილობა", 41 | "Mark as" : "მონიშვნა როგორც", 42 | "Add a rule" : "წესის დამატება" 43 | },"pluralForm" :"nplurals=2; plural=(n!=1);" 44 | } -------------------------------------------------------------------------------- /l10n/ka_GE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "გასუფთავება", 5 | "Infected" : "დაზიანებულია", 6 | "Unchecked" : "შეუმოწმებელია", 7 | "Scanner exit status" : "სკანერის გათიშვის სტატუსი", 8 | "Scanner output" : "სკანერის გამოცემა", 9 | "Saving…" : "მიმდინარეობს დამახსოვრება...", 10 | "Antivirus" : "ანტივირუსი", 11 | "Virus %s is detected in the file. Upload cannot be completed." : "ფაილში აღმოჩენილია ვირუსი %s. ატვირთვა ვერ დასრულდება.", 12 | "Saved" : "შენახულია", 13 | "Greetings {user}," : "გამარჯობა {user},", 14 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "ბოდიში, მაგრამ ფაილში, რომლის ატვირთვაც სცადეთ, აღმოჩნდა ვირუსი და გაუქმდა.", 15 | "This email is a notification from {host}. Please, do not reply." : "ეს ელ-ფოსტა შეტყობინებაა ჰოსტიდან {host}. გთხოვთ ნუ უპასუხებთ.", 16 | "File uploaded: {file}" : "ფაილი აიტვირთა: {file}", 17 | "Mode" : "რეჟიმი", 18 | "Socket" : "სოკეტი", 19 | "Not required in Executable Mode." : "შესრულებად რეჟიმში არაა აუცილებელი.", 20 | "Host" : "ჰოსტი", 21 | "Address of Antivirus Host." : "ანტივირუსის ჰოსტის მისამართი.", 22 | "Port" : "პორტი", 23 | "Port number of Antivirus Host." : "ანტივირუსის ჰოსტის პორტის ნომერი.", 24 | "Select" : "არჩევა", 25 | "Stream Length" : "სტრიმის სიგრძე", 26 | "ClamAV StreamMaxLength value in bytes." : "ClamAV StreamMaxLength მნიშვნელობა ბაიტებში.", 27 | "bytes" : "ბაიტები", 28 | "Path to clamscan" : "clamscan მისამართი", 29 | "Path to clamscan executable." : "clamscan შესრულებადის მისამართი.", 30 | "Not required in Daemon Mode." : "Daemon რეჟიმში არაა აუცილებელი.", 31 | "Extra command line options (comma-separated)" : "ექსტრა კონსოლის პარამეტრი (გამოყოფილი-მძიმით)", 32 | "Only log" : "მხოლოდ ჩაიწეროს ლოგი", 33 | "Delete file" : "გაუქმდეს ფაილი", 34 | "Yes" : "დიახ", 35 | "Save" : "შენახვა", 36 | "Advanced" : "მოწინავე", 37 | "Rules" : "წესები", 38 | "Clear All" : "ყველას გასუფთავება", 39 | "Reset to defaults" : "საწყის რეჟიმზე დაბრუნება", 40 | "Match by" : "დამთხვევა", 41 | "Scanner exit status or signature to search" : "სკანერის გათიშვის სტატუსი ან ხელმოწერები ძიებისთვის", 42 | "Description" : "აღწერილობა", 43 | "Mark as" : "მონიშვნა როგორც", 44 | "Add a rule" : "წესის დამატება" 45 | }, 46 | "nplurals=2; plural=(n!=1);"); 47 | -------------------------------------------------------------------------------- /tests/DummyClam.php: -------------------------------------------------------------------------------- 1 | socketDN = $socketPath; 20 | } 21 | 22 | public function startServer() { 23 | $this->socket = stream_socket_server($this->socketDN, $errNo, $errStr); 24 | if (!is_resource($this->socket)) { 25 | throw new \Exception( 26 | sprintf( 27 | 'Unable to open socket. Error code: %s. Error message: "%s"', 28 | $errNo, 29 | $errStr 30 | ) 31 | ); 32 | } 33 | // listen 34 | while (true) { 35 | $connection = @stream_socket_accept($this->socket, -1); 36 | if (is_resource($connection)) { 37 | //echo 'connected' . PHP_EOL; 38 | $this->handleConnection($connection); 39 | @fclose($connection); 40 | } 41 | } 42 | } 43 | protected function handleConnection($connection) { 44 | $buffer = ''; 45 | $isAborted = false; 46 | $command = fread($connection, 10); 47 | //starts from INSTREAM\n from the first packet; 48 | 49 | if ($command !== "nINSTREAM\n") { 50 | return; 51 | } 52 | //echo $command; 53 | do { 54 | $binaryChunkSize = @fread($connection, 4); 55 | $chunkSizeArray = unpack('Nlength', $binaryChunkSize); 56 | $chunkSize = $chunkSizeArray['length']; 57 | if ($chunkSize === 0) { 58 | break; 59 | } 60 | 61 | $dataChunk = ''; 62 | do { 63 | $dataChunk .= @fread($connection, $chunkSize); 64 | } while (is_resource($connection) && strlen($dataChunk) !== $chunkSize); 65 | 66 | $nextBufferSize = strlen($buffer) + strlen($dataChunk); 67 | if ($nextBufferSize > self::TEST_STREAM_SIZE) { 68 | $isAborted = true; 69 | break; 70 | } 71 | 72 | $buffer = $buffer . $dataChunk; 73 | } while (true); 74 | 75 | if (!$isAborted) { 76 | $response = strpos($buffer, self::TEST_SIGNATURE) !== false 77 | ? 'Ohoho: Criminal.Joboholic FOUND' 78 | : 'Scanned OK' 79 | ; 80 | //echo str_replace('0', '', $buffer) . $response; 81 | fwrite($connection, $response); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/Command/BackgroundScan.php: -------------------------------------------------------------------------------- 1 | backgroundScanner = $backgroundScanner; 28 | $this->eventDispatcher = $eventDispatcher; 29 | $this->appConfig = $appConfig; 30 | } 31 | 32 | protected function configure() { 33 | parent::configure(); 34 | 35 | $this 36 | ->setName('files_antivirus:background-scan') 37 | ->setDescription('Run the background scan') 38 | ->addOption('max', 'm', InputOption::VALUE_REQUIRED, 'Maximum number of files to process'); 39 | } 40 | 41 | protected function execute(InputInterface $input, OutputInterface $output): int { 42 | $verbose = (bool)$input->getOption('verbose'); 43 | if ($this->appConfig->getAppValue('av_background_scan') !== 'on') { 44 | // Background checking disabled no need to continue 45 | $output->writeln('Antivirus background scan disabled'); 46 | return 0; 47 | } 48 | $max = (int)$input->getOption('max'); 49 | if (!$max) { 50 | $max = PHP_INT_MAX; 51 | } 52 | 53 | if ($verbose) { 54 | $this->eventDispatcher->addListener(BeforeBackgroundScanEvent::class, function (BeforeBackgroundScanEvent $event) use ($output) { 55 | $path = $event->getFile()->getPath(); 56 | $output->writeln("scanning $path"); 57 | }); 58 | } 59 | 60 | $count = $this->backgroundScanner->scan($max); 61 | 62 | $output->writeln("scanned $count files"); 63 | if ($count === $max) { 64 | $output->writeln(' there might still be unscanned files remaining'); 65 | } 66 | 67 | return 0; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/Migration/Version10400Date20180929132835.php: -------------------------------------------------------------------------------- 1 | hasTable('files_antivirus')) { 26 | $table = $schema->createTable('files_antivirus'); 27 | $table->addColumn('fileid', 'integer', [ 28 | 'notnull' => true, 29 | 'length' => 4, 30 | 'unsigned' => true, 31 | ]); 32 | $table->addColumn('check_time', 'integer', [ 33 | 'notnull' => true, 34 | 'length' => 4, 35 | 'default' => 0, 36 | 'unsigned' => true, 37 | ]); 38 | $table->setPrimaryKey(['fileid']); 39 | } 40 | 41 | if (!$schema->hasTable('files_avir_status')) { 42 | $table = $schema->createTable('files_avir_status'); 43 | $table->addColumn('id', 'integer', [ 44 | 'autoincrement' => true, 45 | 'notnull' => true, 46 | 'length' => 4, 47 | 'unsigned' => true, 48 | ]); 49 | $table->addColumn('group_id', 'integer', [ 50 | 'notnull' => true, 51 | 'length' => 4, 52 | 'default' => 0, 53 | 'unsigned' => true, 54 | ]); 55 | $table->addColumn('status_type', 'integer', [ 56 | 'notnull' => true, 57 | 'length' => 4, 58 | 'default' => 0, 59 | 'unsigned' => true, 60 | ]); 61 | $table->addColumn('result', 'integer', [ 62 | 'notnull' => true, 63 | 'length' => 4, 64 | 'default' => 0, 65 | ]); 66 | $table->addColumn('match', 'string', [ 67 | 'notnull' => false, 68 | 'length' => 64, 69 | ]); 70 | $table->addColumn('description', 'string', [ 71 | 'notnull' => false, 72 | 'length' => 64, 73 | ]); 74 | $table->addColumn('status', 'integer', [ 75 | 'notnull' => true, 76 | 'length' => 4, 77 | 'default' => 0, 78 | ]); 79 | $table->setPrimaryKey(['id']); 80 | } 81 | return $schema; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /l10n/lt_LT.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Švarus", 3 | "Infected" : "Užkrėstas", 4 | "Saving…" : "Įrašoma…", 5 | "Antivirus" : "Antivirusinė", 6 | "File {file} is infected with {virus}" : "Failas {file} yra užkrėstas {virus}", 7 | "The file has been removed" : "Failas buvo pašalintas", 8 | "File containing {virus} detected" : "Aptiktas failas, kuriame yra {virus}", 9 | "Antivirus detected a virus" : "Antivirusinė aptiko virusą", 10 | "Virus %s is detected in the file. Upload cannot be completed." : "Faile yra aptiktas virusas %s. Įkėlimas negali būti užbaigtas.", 11 | "Saved" : "Įrašyta", 12 | "Antivirus for files" : "Failų antivirusinė", 13 | "Greetings {user}," : "Sveiki {user},", 14 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Atleiskite, tačiau faile, kurį bandėte įkelti, buvo aptikta kenkimo programinė įranga ir jis turėjo būti ištrintas.", 15 | "This email is a notification from {host}. Please, do not reply." : "Šis el. laiškas yra pranešimas iš {host}. Prašome neatsakyti.", 16 | "File uploaded: {file}" : "Failas įkeltas: {file}", 17 | "Antivirus for Files" : "Failų antivirusinė", 18 | "Mode" : "Veiksena", 19 | "ClamAV Executable" : "ClamAV vykdomasis", 20 | "ClamAV Daemon" : "ClamAV tarnyba", 21 | "ClamAV Daemon (Socket)" : "ClamAV tarnyba (Lizdas)", 22 | "ICAP server" : "ICAP serveris", 23 | "Socket" : "Lizdas", 24 | "ClamAV Socket." : "ClamAV lizdas.", 25 | "Host" : "Serveris", 26 | "Port" : "Prievadas", 27 | "TLS" : "TLS", 28 | "Use TLS encryption." : "Naudoti TLS šifravimą.", 29 | "Select" : "Pasirinkti", 30 | "Stream Length" : "Srauto ilgis", 31 | "ClamAV StreamMaxLength value in bytes." : "ClamAV StreamMaxLength reikšmė, baitais.", 32 | "bytes" : "baitų", 33 | "Path to clamscan" : "Kelias į clamscan", 34 | "Path to clamscan executable." : "Kelias į clamscan vykdomąjį.", 35 | "Delete file" : "Ištrinti failą", 36 | "Yes" : "Taip", 37 | "No" : "Ne", 38 | "Save" : "Įrašyti", 39 | "Advanced" : "Išplėstiniai", 40 | "Rules" : "Taisyklės", 41 | "Clear All" : "Išvalyti viską", 42 | "Reset to defaults" : "Atstatyti į numatytuosius", 43 | "Description" : "Aprašas", 44 | "Mark as" : "Žymėti kaip", 45 | "Add a rule" : "Pridėti taisyklę" 46 | },"pluralForm" :"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);" 47 | } -------------------------------------------------------------------------------- /lib/Db/Rule.php: -------------------------------------------------------------------------------- 1 | $this->id, 85 | 'group_id' => $this->groupId, 86 | 'status_type' => $this->statusType, 87 | 'result' => $this->result, 88 | 'match' => $this->match, 89 | 'description' => $this->description, 90 | 'status' => $this->status 91 | ]; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /tests/TestBase.php: -------------------------------------------------------------------------------- 1 | db = \OC::$server->getDatabaseConnection(); 36 | 37 | $this->application = new Application(); 38 | $this->container = $this->application->getContainer(); 39 | 40 | $this->config = $this->getMockBuilder(AppConfig::class) 41 | ->disableOriginalConstructor() 42 | ->setMethods(['getAvPath', 'getAvChunkSize', 'getAvMode', 'getAppValue', 'getAvHost', 'getAvPort', 'getAvBlockUnscannable']) 43 | ->getMock(); 44 | 45 | $this->config->expects($this->any()) 46 | ->method('getAvPath') 47 | ->will($this->returnValue(__DIR__ . '/avir.sh')); 48 | $this->config->expects($this->any()) 49 | ->method('getAvChunkSize') 50 | ->will($this->returnValue(1024)); 51 | $this->config->expects($this->any()) 52 | ->method('getAvMode') 53 | ->will($this->returnValue('executable')); 54 | $this->config->expects($this->any()) 55 | ->method('getAppValue') 56 | ->will($this->returnCallback([$this, 'getAppValue'])); 57 | $this->config->expects($this->any()) 58 | ->method('getAvHost') 59 | ->will($this->returnValue('localhost')); 60 | $this->config->expects($this->any()) 61 | ->method('getAvPort') 62 | ->will($this->returnValue('5555')); 63 | 64 | $this->l10n = $this->getMockBuilder(IL10N::class) 65 | ->disableOriginalConstructor() 66 | ->getMock(); 67 | $this->l10n->method('t')->will($this->returnArgument(0)); 68 | } 69 | 70 | public function getAppValue($methodName) { 71 | switch ($methodName) { 72 | case 'getAvPath': 73 | return __DIR__ . '/avir.sh'; 74 | case 'getAvMode': 75 | return 'executable'; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /l10n/lt_LT.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Švarus", 5 | "Infected" : "Užkrėstas", 6 | "Saving…" : "Įrašoma…", 7 | "Antivirus" : "Antivirusinė", 8 | "File {file} is infected with {virus}" : "Failas {file} yra užkrėstas {virus}", 9 | "The file has been removed" : "Failas buvo pašalintas", 10 | "File containing {virus} detected" : "Aptiktas failas, kuriame yra {virus}", 11 | "Antivirus detected a virus" : "Antivirusinė aptiko virusą", 12 | "Virus %s is detected in the file. Upload cannot be completed." : "Faile yra aptiktas virusas %s. Įkėlimas negali būti užbaigtas.", 13 | "Saved" : "Įrašyta", 14 | "Antivirus for files" : "Failų antivirusinė", 15 | "Greetings {user}," : "Sveiki {user},", 16 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Atleiskite, tačiau faile, kurį bandėte įkelti, buvo aptikta kenkimo programinė įranga ir jis turėjo būti ištrintas.", 17 | "This email is a notification from {host}. Please, do not reply." : "Šis el. laiškas yra pranešimas iš {host}. Prašome neatsakyti.", 18 | "File uploaded: {file}" : "Failas įkeltas: {file}", 19 | "Antivirus for Files" : "Failų antivirusinė", 20 | "Mode" : "Veiksena", 21 | "ClamAV Executable" : "ClamAV vykdomasis", 22 | "ClamAV Daemon" : "ClamAV tarnyba", 23 | "ClamAV Daemon (Socket)" : "ClamAV tarnyba (Lizdas)", 24 | "ICAP server" : "ICAP serveris", 25 | "Socket" : "Lizdas", 26 | "ClamAV Socket." : "ClamAV lizdas.", 27 | "Host" : "Serveris", 28 | "Port" : "Prievadas", 29 | "TLS" : "TLS", 30 | "Use TLS encryption." : "Naudoti TLS šifravimą.", 31 | "Select" : "Pasirinkti", 32 | "Stream Length" : "Srauto ilgis", 33 | "ClamAV StreamMaxLength value in bytes." : "ClamAV StreamMaxLength reikšmė, baitais.", 34 | "bytes" : "baitų", 35 | "Path to clamscan" : "Kelias į clamscan", 36 | "Path to clamscan executable." : "Kelias į clamscan vykdomąjį.", 37 | "Delete file" : "Ištrinti failą", 38 | "Yes" : "Taip", 39 | "No" : "Ne", 40 | "Save" : "Įrašyti", 41 | "Advanced" : "Išplėstiniai", 42 | "Rules" : "Taisyklės", 43 | "Clear All" : "Išvalyti viską", 44 | "Reset to defaults" : "Atstatyti į numatytuosius", 45 | "Description" : "Aprašas", 46 | "Mark as" : "Žymėti kaip", 47 | "Add a rule" : "Pridėti taisyklę" 48 | }, 49 | "nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);"); 50 | -------------------------------------------------------------------------------- /l10n/lv.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Tīrs", 3 | "Infected" : "Inficēts", 4 | "Unchecked" : "Neatzīmēts", 5 | "Scanner exit status" : "Skenera izejas stāvoklis", 6 | "Scanner output" : "Skenera izvade", 7 | "Saving…" : "Saglabā...", 8 | "Antivirus" : "Antivīruss", 9 | "File {file} is infected with {virus}" : "Datne {file] ir inficēta ar {virus}", 10 | "The file has been removed" : "Šī datne ir noņemta", 11 | "File containing {virus} detected" : "Datne, kas satur {virus} atklāta", 12 | "Antivirus detected a virus" : "Antivīruss atklāja vīrusu", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Datnē ir noteikts vīruss %s. Augšupielādi nevar pabeigt.", 14 | "%s. Upload cannot be completed." : "%s. Augšupielādi nevar pabeigt.", 15 | "Saved" : "Saglabāts", 16 | "Antivirus for files" : "Antīvīruss datnēm", 17 | "Greetings {user}," : "Sveiciens {user}.", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Atvainojamies, bet datnē, kuru mēģināji augšupielādēt, tika noteikta ļaunatūra, un to nācās izdzēst.", 19 | "This email is a notification from {host}. Please, do not reply." : "Šis e-pasta ziņojums ir paziņojums no {host}. Lūgums neatbildēt.", 20 | "File uploaded: {file}" : "Datne augšupielādēta: {file}", 21 | "Antivirus for Files" : "Antīvīruss datnēm", 22 | "Mode" : "Režīms", 23 | "Host" : "Resursdators", 24 | "Address of Antivirus Host." : "Antīvīrusa Hosta adrese", 25 | "Port" : "Ports", 26 | "TLS" : "TLS", 27 | "Select" : "Atzīmēt", 28 | "bytes" : "baiti", 29 | "Path to clamscan" : "Ceļš uz clamscan", 30 | "Path to clamscan executable." : "Ceļš uz clamscan izpildīšanas datni", 31 | "Not required in Daemon Mode." : "Nav vajadzīgs Daemon ŗežīmā.", 32 | "When infected files are found during a background scan" : "Kad inficētas datnes ir atrastas fona skenēšanā", 33 | "Only log" : "Tikai logot", 34 | "Delete file" : "Izdzēst datni", 35 | "Yes" : "Jā", 36 | "No" : "Nē", 37 | "Save" : "Saglabāt", 38 | "Advanced" : "Paplašināti", 39 | "Rules" : "Noteikumi", 40 | "Clear All" : "Notīrīt visu", 41 | "Reset to defaults" : "Atiestatīt uz noklusējuma", 42 | "Scanner exit status or signature to search" : "Nolasītāja izejas stāvoklis vai paraksts, ko meklēt", 43 | "Description" : "Apraksts", 44 | "Mark as" : "Atzīmēt kā", 45 | "Add a rule" : "Pievienot noteikumu" 46 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" 47 | } -------------------------------------------------------------------------------- /lib/Command/Mark.php: -------------------------------------------------------------------------------- 1 | rootFolder = $rootFolder; 31 | $this->itemFactory = $itemFactory; 32 | } 33 | 34 | protected function configure() { 35 | parent::configure(); 36 | 37 | $this 38 | ->setName('files_antivirus:mark') 39 | ->setDescription('Mark a file as scanned or unscanned') 40 | ->addOption('forever', 'f', InputOption::VALUE_NONE, 'When marking a file as scanned, set it to never rescan the file in the future') 41 | ->addArgument('file', InputArgument::REQUIRED, 'Path of the file to mark') 42 | ->addArgument('mode', InputArgument::REQUIRED, 'Either scanned or unscanned'); 43 | } 44 | 45 | protected function execute(InputInterface $input, OutputInterface $output): int { 46 | $path = $input->getArgument('file'); 47 | $forever = $input->getOption('forever'); 48 | $mode = $input->getArgument('mode'); 49 | try { 50 | $node = $this->rootFolder->get($path); 51 | } catch (NotFoundException $e) { 52 | $output->writeln("$path doesn't exist"); 53 | return 1; 54 | } 55 | if (!$node instanceof File) { 56 | $output->writeln("$path is a folder"); 57 | return 1; 58 | } 59 | 60 | if ($mode !== 'scanned' && $mode !== 'unscanned') { 61 | $output->writeln("invalid mode $mode, please specify either scanned or unscanned"); 62 | return 1; 63 | } 64 | 65 | $item = $this->itemFactory->newItem($node); 66 | if ($mode === 'unscanned') { 67 | $item->removeCheckTime(); 68 | } elseif ($forever) { 69 | $item->updateCheckTime(0x7fffffff); // check time is still 32b 70 | } else { 71 | $item->processClean(); 72 | } 73 | 74 | return 0; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /l10n/lv.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Tīrs", 5 | "Infected" : "Inficēts", 6 | "Unchecked" : "Neatzīmēts", 7 | "Scanner exit status" : "Skenera izejas stāvoklis", 8 | "Scanner output" : "Skenera izvade", 9 | "Saving…" : "Saglabā...", 10 | "Antivirus" : "Antivīruss", 11 | "File {file} is infected with {virus}" : "Datne {file] ir inficēta ar {virus}", 12 | "The file has been removed" : "Šī datne ir noņemta", 13 | "File containing {virus} detected" : "Datne, kas satur {virus} atklāta", 14 | "Antivirus detected a virus" : "Antivīruss atklāja vīrusu", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Datnē ir noteikts vīruss %s. Augšupielādi nevar pabeigt.", 16 | "%s. Upload cannot be completed." : "%s. Augšupielādi nevar pabeigt.", 17 | "Saved" : "Saglabāts", 18 | "Antivirus for files" : "Antīvīruss datnēm", 19 | "Greetings {user}," : "Sveiciens {user}.", 20 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Atvainojamies, bet datnē, kuru mēģināji augšupielādēt, tika noteikta ļaunatūra, un to nācās izdzēst.", 21 | "This email is a notification from {host}. Please, do not reply." : "Šis e-pasta ziņojums ir paziņojums no {host}. Lūgums neatbildēt.", 22 | "File uploaded: {file}" : "Datne augšupielādēta: {file}", 23 | "Antivirus for Files" : "Antīvīruss datnēm", 24 | "Mode" : "Režīms", 25 | "Host" : "Resursdators", 26 | "Address of Antivirus Host." : "Antīvīrusa Hosta adrese", 27 | "Port" : "Ports", 28 | "TLS" : "TLS", 29 | "Select" : "Atzīmēt", 30 | "bytes" : "baiti", 31 | "Path to clamscan" : "Ceļš uz clamscan", 32 | "Path to clamscan executable." : "Ceļš uz clamscan izpildīšanas datni", 33 | "Not required in Daemon Mode." : "Nav vajadzīgs Daemon ŗežīmā.", 34 | "When infected files are found during a background scan" : "Kad inficētas datnes ir atrastas fona skenēšanā", 35 | "Only log" : "Tikai logot", 36 | "Delete file" : "Izdzēst datni", 37 | "Yes" : "Jā", 38 | "No" : "Nē", 39 | "Save" : "Saglabāt", 40 | "Advanced" : "Paplašināti", 41 | "Rules" : "Noteikumi", 42 | "Clear All" : "Notīrīt visu", 43 | "Reset to defaults" : "Atiestatīt uz noklusējuma", 44 | "Scanner exit status or signature to search" : "Nolasītāja izejas stāvoklis vai paraksts, ko meklēt", 45 | "Description" : "Apraksts", 46 | "Mark as" : "Atzīmēt kā", 47 | "Add a rule" : "Pievienot noteikumu" 48 | }, 49 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); 50 | -------------------------------------------------------------------------------- /lib/ICAP/ICAPClient.php: -------------------------------------------------------------------------------- 1 | host = $host; 30 | $this->port = $port; 31 | $this->connectTimeout = $connectTimeout; 32 | } 33 | 34 | /** 35 | * @param callable(string): void $callback 36 | * @return void 37 | */ 38 | public function setDebugCallback(callable $callback): void { 39 | $this->debugCallback = $callback; 40 | } 41 | 42 | /** 43 | * Connect to ICAP server 44 | * 45 | * @return resource 46 | */ 47 | protected function connect() { 48 | $stream = @\stream_socket_client( 49 | "tcp://{$this->host}:{$this->port}", 50 | $errorCode, 51 | $errorMessage, 52 | $this->connectTimeout 53 | ); 54 | 55 | if (!$stream) { 56 | throw new RuntimeException( 57 | "Cannot connect to \"tcp://{$this->host}:{$this->port}\": $errorMessage (code $errorCode)" 58 | ); 59 | } 60 | 61 | socket_set_timeout($stream, 600); 62 | 63 | return $stream; 64 | } 65 | 66 | /** 67 | * Send REQMOD request 68 | * 69 | * @param string $service ICAP service 70 | * @param array $headers 71 | * @param array $requestHeaders 72 | * @return ICAPRequest Response array 73 | */ 74 | public function reqmod(string $service, array $headers, array $requestHeaders): ICAPRequest { 75 | $stream = $this->connect(); 76 | return new ICAPRequest($stream, $this->host, $service, 'REQMOD', $headers, $requestHeaders, [], $this->debugCallback); 77 | } 78 | 79 | /** 80 | * Send RESPMOD request 81 | * 82 | * @param string $service ICAP service 83 | * @param array $headers 84 | * @param array $requestHeaders 85 | * @return ICAPRequest Response array 86 | */ 87 | public function respmod(string $service, array $headers, array $requestHeaders, array $responseHeaders): ICAPRequest { 88 | $stream = $this->connect(); 89 | return new ICAPRequest($stream, $this->host, $service, 'RESPMOD', $headers, $requestHeaders, $responseHeaders, $this->debugCallback); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/Db/ItemMapper.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class ItemMapper extends QBMapper { 21 | public function __construct(IDBConnection $db) { 22 | parent::__construct($db, 'files_antivirus', Item::class); 23 | } 24 | 25 | /** 26 | * Find rule by id 27 | * 28 | * @param int $fileid 29 | * @return Entity 30 | * @throws DoesNotExistException 31 | */ 32 | public function findByFileId(int $fileid): Entity { 33 | $query = $this->db->getQueryBuilder(); 34 | $query->select('*') 35 | ->from('files_antivirus') 36 | ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileid, IQueryBuilder::PARAM_INT))); 37 | return $this->findEntity($query); 38 | } 39 | 40 | public function delete(Entity $entity): Entity { 41 | if (!($entity instanceof Item)) { 42 | throw new \InvalidArgumentException(); 43 | } 44 | 45 | $query = $this->db->getQueryBuilder(); 46 | $query->delete('files_antivirus') 47 | ->where($query->expr()->eq('fileid', $query->createNamedParameter($entity->getFileid(), IQueryBuilder::PARAM_INT))); 48 | $query->executeStatement(); 49 | 50 | return $entity; 51 | } 52 | 53 | /** 54 | * Creates a new entry in the db from an entity 55 | * 56 | * @param Item $entity the entity that should be created 57 | * @return Item the saved entity with the set id 58 | * @throws Exception 59 | * @since 14.0.0 60 | */ 61 | public function insert(Entity $entity): Entity { 62 | // get updated fields to save, fields have to be set using a setter to 63 | // be saved 64 | $properties = $entity->getUpdatedFields(); 65 | 66 | $qb = $this->db->getQueryBuilder(); 67 | $qb->insert($this->tableName); 68 | 69 | // build the fields 70 | foreach ($properties as $property => $updated) { 71 | $column = $entity->propertyToColumn($property); 72 | $getter = 'get' . ucfirst($property); 73 | $value = $entity->$getter(); 74 | 75 | $type = $this->getParameterTypeForProperty($entity, $property); 76 | $qb->setValue($column, $qb->createNamedParameter($value, $type)); 77 | } 78 | 79 | $qb->executeStatement(); 80 | 81 | return $entity; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lib/Command/Status.php: -------------------------------------------------------------------------------- 1 | backgroundScanner = $backgroundScanner; 24 | $this->appConfig = $appConfig; 25 | } 26 | 27 | protected function configure() { 28 | parent::configure(); 29 | 30 | $this 31 | ->setName('files_antivirus:status') 32 | ->setDescription('Antivirus scanner status'); 33 | } 34 | 35 | protected function execute(InputInterface $input, OutputInterface $output): int { 36 | $verbose = (bool)$input->getOption('verbose'); 37 | if ($this->appConfig->getAppValue('av_background_scan') !== 'on') { 38 | // Background checking disabled no need to continue 39 | $output->writeln('Antivirus background scan disabled'); 40 | return 0; 41 | } 42 | 43 | $unscanned = $this->backgroundScanner->getUnscannedFiles(); 44 | $count = $this->processFiles($unscanned, $output, $verbose, 'is unscanned'); 45 | $output->writeln("$count unscanned files"); 46 | 47 | $rescan = $this->backgroundScanner->getToRescanFiles(); 48 | $count = $this->processFiles($rescan, $output, $verbose, 'is scheduled for re-scan'); 49 | $output->writeln("$count files scheduled for re-scan"); 50 | 51 | $outdated = $this->backgroundScanner->getOutdatedFiles(); 52 | $count = $this->processFiles($outdated, $output, $verbose, 'has been updated'); 53 | $output->writeln("$count have been updated since the last scan"); 54 | 55 | return 0; 56 | } 57 | 58 | /** 59 | * @param iterable $fileIds 60 | * @return int 61 | */ 62 | private function processFiles(iterable $fileIds, OutputInterface $output, bool $verbose, string $info): int { 63 | $count = 0; 64 | 65 | foreach ($fileIds as $fileId) { 66 | if ($verbose) { 67 | $node = $this->backgroundScanner->getNodeForFile($fileId); 68 | if ($node) { 69 | $path = $node->getPath(); 70 | $output->writeln(" $path $info"); 71 | } else { 72 | $output->writeln(" warning: no file found for file $fileId"); 73 | } 74 | } 75 | $count++; 76 | } 77 | 78 | return $count; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/Controller/RuleController.php: -------------------------------------------------------------------------------- 1 | ruleMapper = $ruleMapper; 24 | } 25 | 26 | /** 27 | * Returns all rules 28 | * @return JSONResponse 29 | */ 30 | public function listAll() { 31 | $statuses = $this->ruleMapper->findAll(); 32 | return new JSONResponse(['statuses' => $statuses]); 33 | } 34 | 35 | /** 36 | * Removes all rules 37 | * @return JSONResponse 38 | */ 39 | public function clear() { 40 | $this->ruleMapper->deleteAll(); 41 | return new JSONResponse(); 42 | } 43 | 44 | /** 45 | * Resets a table to initial state 46 | * @return JSONResponse 47 | */ 48 | public function reset() { 49 | $this->ruleMapper->deleteAll(); 50 | $this->ruleMapper->populate(); 51 | return new JSONResponse(); 52 | } 53 | 54 | /** 55 | * Adds/Updates a rule 56 | * @param int $id 57 | * @param int $statusType 58 | * @param string $match 59 | * @param string $description 60 | * @param int $status 61 | * @return JSONResponse 62 | */ 63 | public function save($id, $statusType, $match, $description, $status) { 64 | if ($id) { 65 | $rule = $this->ruleMapper->find($id); 66 | } else { 67 | $rule = new Rule(); 68 | } 69 | 70 | $rule->setStatusType($statusType); 71 | $rule->setDescription($description); 72 | $rule->setStatus($status); 73 | 74 | if ($statusType === Rule::RULE_TYPE_CODE) { 75 | $rule->setResult((int)$match); 76 | } else { 77 | $rule->setMatch($match); 78 | } 79 | 80 | if ($id) { 81 | $newRule = $this->ruleMapper->update($rule); 82 | } else { 83 | $newRule = $this->ruleMapper->insert($rule); 84 | } 85 | 86 | return new JSONResponse($newRule); 87 | } 88 | 89 | /** 90 | * Deletes a rule 91 | * @param int $id 92 | * @return JSONResponse 93 | */ 94 | public function delete($id) { 95 | try { 96 | $rule = $this->ruleMapper->find($id); 97 | $this->ruleMapper->delete($rule); 98 | } catch (\Exception $e) { 99 | //TODO: Handle 100 | } 101 | return new JSONResponse($rule); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /l10n/fi.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Puhdas", 3 | "Infected" : "Saastunut", 4 | "Unchecked" : "Ei tarkistettu", 5 | "Scanner output" : "Tarkistimen tuloste", 6 | "Saving…" : "Tallennetaan…", 7 | "Antivirus" : "Virustorjunta", 8 | "File {file} is infected with {virus}" : "Tiedosto {file} on saastunut viruksella {virus}", 9 | "The file has been removed" : "Tiedosto on poistettu", 10 | "File containing {virus} detected" : "Tiedosto sisältäen viruksen {virus} havaittu", 11 | "Antivirus detected a virus" : "Virustorjunta havaitsi viruksen", 12 | "Virus %s is detected in the file. Upload cannot be completed." : "Virus %s havaittiin tiedostossa. Lähetystä ei voi suorittaa loppuun.", 13 | "Saved" : "Tallennettu", 14 | "Antivirus for files" : "Virustorjunta tiedostoille", 15 | "An antivirus app for Nextcloud" : "Virustorjuntaohjelmisto Nextcloudille", 16 | "Greetings {user}," : "Hei {user},", 17 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Valitettavasti lähettämästäsi tiedostosta löytyi haittaohjelma, joten lähettämäsi tiedosto poistettiin.", 18 | "This email is a notification from {host}. Please, do not reply." : "Tämä on ilmoitus sivustolta {host}. Älä vastaa tähän viestiin.", 19 | "File uploaded: {file}" : "Tiedosto lähetetty: {file}", 20 | "Antivirus for Files" : "Virustorjunta tiedostoille", 21 | "Mode" : "Tila", 22 | "ClamAV Executable" : "ClamAV-suoritustiedosto", 23 | "ClamAV Daemon" : "ClamAV-taustapalvelu", 24 | "Kaspersky Daemon" : "Kaspersky-taustapalvelu", 25 | "ICAP server" : "ICAP-palvelin", 26 | "Not required in Executable Mode." : "Ei vaadittu suoritettavassa tilassa.", 27 | "Host" : "Palvelin", 28 | "Address of Antivirus Host." : "Virustorjuntapalvelimen osoite.", 29 | "Port" : "Portti", 30 | "Port number of Antivirus Host." : "Virustorjuntapalvelimen portti.", 31 | "TLS" : "TLS", 32 | "Use TLS encryption." : "Käytä TLS-salausta.", 33 | "ICAP preset" : "ICAP-esiasetus", 34 | "Select" : "Valitse", 35 | "ICAP service" : "ICAP-palvelu", 36 | "bytes" : "tavua", 37 | "Path to clamscan" : "Clamscanin polku", 38 | "Path to clamscan executable." : "Polku suoritettavaan clamscan-tiedostoon.", 39 | "Not required in Daemon Mode." : "Ei vaadittu taustapalvelutilassa.", 40 | "Only log" : "Vain logitus", 41 | "Delete file" : "Poista tiedosto", 42 | "Yes" : "Kyllä", 43 | "No" : "Ei", 44 | "Save" : "Tallenna", 45 | "Advanced" : "Lisäasetukset", 46 | "Rules" : "Säännöt", 47 | "Clear All" : "Tyhjennä kaikki", 48 | "Reset to defaults" : "Palauta oletusarvot", 49 | "Description" : "Kuvaus", 50 | "Mark as" : "Merkitse", 51 | "Add a rule" : "Lisää sääntö" 52 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 53 | } -------------------------------------------------------------------------------- /l10n/fi.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Puhdas", 5 | "Infected" : "Saastunut", 6 | "Unchecked" : "Ei tarkistettu", 7 | "Scanner output" : "Tarkistimen tuloste", 8 | "Saving…" : "Tallennetaan…", 9 | "Antivirus" : "Virustorjunta", 10 | "File {file} is infected with {virus}" : "Tiedosto {file} on saastunut viruksella {virus}", 11 | "The file has been removed" : "Tiedosto on poistettu", 12 | "File containing {virus} detected" : "Tiedosto sisältäen viruksen {virus} havaittu", 13 | "Antivirus detected a virus" : "Virustorjunta havaitsi viruksen", 14 | "Virus %s is detected in the file. Upload cannot be completed." : "Virus %s havaittiin tiedostossa. Lähetystä ei voi suorittaa loppuun.", 15 | "Saved" : "Tallennettu", 16 | "Antivirus for files" : "Virustorjunta tiedostoille", 17 | "An antivirus app for Nextcloud" : "Virustorjuntaohjelmisto Nextcloudille", 18 | "Greetings {user}," : "Hei {user},", 19 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Valitettavasti lähettämästäsi tiedostosta löytyi haittaohjelma, joten lähettämäsi tiedosto poistettiin.", 20 | "This email is a notification from {host}. Please, do not reply." : "Tämä on ilmoitus sivustolta {host}. Älä vastaa tähän viestiin.", 21 | "File uploaded: {file}" : "Tiedosto lähetetty: {file}", 22 | "Antivirus for Files" : "Virustorjunta tiedostoille", 23 | "Mode" : "Tila", 24 | "ClamAV Executable" : "ClamAV-suoritustiedosto", 25 | "ClamAV Daemon" : "ClamAV-taustapalvelu", 26 | "Kaspersky Daemon" : "Kaspersky-taustapalvelu", 27 | "ICAP server" : "ICAP-palvelin", 28 | "Not required in Executable Mode." : "Ei vaadittu suoritettavassa tilassa.", 29 | "Host" : "Palvelin", 30 | "Address of Antivirus Host." : "Virustorjuntapalvelimen osoite.", 31 | "Port" : "Portti", 32 | "Port number of Antivirus Host." : "Virustorjuntapalvelimen portti.", 33 | "TLS" : "TLS", 34 | "Use TLS encryption." : "Käytä TLS-salausta.", 35 | "ICAP preset" : "ICAP-esiasetus", 36 | "Select" : "Valitse", 37 | "ICAP service" : "ICAP-palvelu", 38 | "bytes" : "tavua", 39 | "Path to clamscan" : "Clamscanin polku", 40 | "Path to clamscan executable." : "Polku suoritettavaan clamscan-tiedostoon.", 41 | "Not required in Daemon Mode." : "Ei vaadittu taustapalvelutilassa.", 42 | "Only log" : "Vain logitus", 43 | "Delete file" : "Poista tiedosto", 44 | "Yes" : "Kyllä", 45 | "No" : "Ei", 46 | "Save" : "Tallenna", 47 | "Advanced" : "Lisäasetukset", 48 | "Rules" : "Säännöt", 49 | "Clear All" : "Tyhjennä kaikki", 50 | "Reset to defaults" : "Palauta oletusarvot", 51 | "Description" : "Kuvaus", 52 | "Mark as" : "Merkitse", 53 | "Add a rule" : "Lisää sääntö" 54 | }, 55 | "nplurals=2; plural=(n != 1);"); 56 | -------------------------------------------------------------------------------- /l10n/is.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Hreint", 3 | "Infected" : "Smitað", 4 | "Unchecked" : "Ekki skoðað", 5 | "Scanner exit status" : "Staða skanna þegar hætt var", 6 | "Scanner output" : "Úttak skanna", 7 | "Saving…" : "Vista…", 8 | "Antivirus" : "Vírusvörn", 9 | "File {file} is infected with {virus}" : "Skráin {file} er smituð af {virus}", 10 | "The file has been removed" : "Skráin var fjarlægð", 11 | "File containing {virus} detected" : "Fann skrá sem inniheldur {virus}", 12 | "Antivirus detected a virus" : "Vírusvörnin fann vírus", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Vírusinn %s finnst í skránni. Ekki er hægt að ljúka innsendingu.", 14 | "Saved" : "Vistað", 15 | "Antivirus for files" : "Vírusvarnarforrit fyrir skrár", 16 | "Greetings {user}," : "Daginn {user},", 17 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Því miður, en það fannst spillifarmur í skrá sem þú varst að reyna að senda inn og því þurfti að eyða henni.", 18 | "This email is a notification from {host}. Please, do not reply." : "Þessi tölvupóstur er tilkynning frá {host}. Ekki svara honum.", 19 | "File uploaded: {file}" : "Innsend skrá: {file}", 20 | "Antivirus for Files" : "Vírusvarnarforrit fyrir skrár", 21 | "Mode" : "Hamur", 22 | "Socket" : "Rafmagnsinnstunga", 23 | "Not required in Executable Mode." : "Ekki nauðsynlegt í keyrsluham.", 24 | "Host" : "Netþjónn", 25 | "Address of Antivirus Host." : "Vistfang vírusvarnavélar.", 26 | "Port" : "Gátt", 27 | "Port number of Antivirus Host." : "Gáttarnúmer vírusvarnavélar.", 28 | "TLS" : "TLS", 29 | "Select" : "Velja", 30 | "Stream Length" : "Lengd streymis", 31 | "ClamAV StreamMaxLength value in bytes." : "Gildi ClamAV StreamMaxLength í bætum.", 32 | "bytes" : "bæti", 33 | "Path to clamscan" : "Slóð að clamscan", 34 | "Path to clamscan executable." : "Slóð að clamscan-keyrsluskránni.", 35 | "Not required in Daemon Mode." : "Ekki nauðsynlegt í púkaham.", 36 | "Extra command line options (comma-separated)" : "Auka skipanalínurofar (aðskilið með kommu)", 37 | "When infected files are found during a background scan" : "Þegar smitaðar skrár finnast við bakgrunnsskönnun", 38 | "Only log" : "Aðeins skrá í annál", 39 | "Delete file" : "Eyða skrá", 40 | "Save" : "Vista", 41 | "Advanced" : "Ítarlegt", 42 | "Rules" : "Reglur", 43 | "Clear All" : "Hreinsa allt", 44 | "Reset to defaults" : "Frumstilla á sjálfgefin gildi", 45 | "Match by" : "Samsvara", 46 | "Scanner exit status or signature to search" : "Staða skanna þegar hætt er eða auðkenni (signature) til að leita eftir", 47 | "Description" : "Lýsing", 48 | "Mark as" : "Merkja sem", 49 | "Add a rule" : "Bæta við reglu" 50 | },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" 51 | } -------------------------------------------------------------------------------- /.github/workflows/pr-feedback.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | 6 | # SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-FileCopyrightText: 2023 Marcel Klehr 8 | # SPDX-FileCopyrightText: 2023 Joas Schilling <213943+nickvergessen@users.noreply.github.com> 9 | # SPDX-FileCopyrightText: 2023 Daniel Kesselberg 10 | # SPDX-FileCopyrightText: 2023 Florian Steffens 11 | # SPDX-License-Identifier: MIT 12 | 13 | name: 'Ask for feedback on PRs' 14 | on: 15 | schedule: 16 | - cron: '30 1 * * *' 17 | 18 | permissions: 19 | contents: read 20 | pull-requests: write 21 | 22 | jobs: 23 | pr-feedback: 24 | if: ${{ github.repository_owner == 'nextcloud' }} 25 | runs-on: ubuntu-latest 26 | steps: 27 | - name: The get-github-handles-from-website action 28 | uses: marcelklehr/get-github-handles-from-website-action@06b2239db0a48fe1484ba0bfd966a3ab81a08308 # v1.0.1 29 | id: scrape 30 | with: 31 | website: 'https://nextcloud.com/team/' 32 | 33 | - name: Get blocklist 34 | id: blocklist 35 | run: | 36 | blocklist=$(curl https://raw.githubusercontent.com/nextcloud/.github/master/non-community-usernames.txt | paste -s -d, -) 37 | echo "blocklist=$blocklist" >> "$GITHUB_OUTPUT" 38 | 39 | - uses: marcelklehr/pr-feedback-action@1883b38a033fb16f576875e0cf45f98b857655c4 40 | with: 41 | feedback-message: | 42 | Hello there, 43 | Thank you so much for taking the time and effort to create a pull request to our Nextcloud project. 44 | 45 | We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process. 46 | 47 | Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6 48 | 49 | Thank you for contributing to Nextcloud and we hope to hear from you soon! 50 | 51 | (If you believe you should not receive this message, you can add yourself to the [blocklist](https://github.com/nextcloud/.github/blob/master/non-community-usernames.txt).) 52 | days-before-feedback: 14 53 | start-date: '2024-04-30' 54 | exempt-authors: '${{ steps.blocklist.outputs.blocklist }},${{ steps.scrape.outputs.users }}' 55 | exempt-bots: true 56 | -------------------------------------------------------------------------------- /l10n/es_CO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Limpiar", 3 | "Infected" : "Infectado", 4 | "Unchecked" : "Desmarcado", 5 | "Scanner exit status" : "Estatus de salida del scanner", 6 | "Scanner output" : "Salida del scanner", 7 | "Saving…" : "Guardando...", 8 | "Antivirus" : "Antivirus", 9 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 10 | "The file has been removed" : "El archivo ha sido eliminado", 11 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 12 | "Antivirus detected a virus" : "El antivirus detectó un virus", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 14 | "Saved" : "Guardado", 15 | "Greetings {user}," : "Saludos {user},", 16 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 17 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 18 | "File uploaded: {file}" : "Archivo guardado: {file}", 19 | "Mode" : "Modo", 20 | "Socket" : "Socket", 21 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 22 | "Host" : "Servidor", 23 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 24 | "Port" : "Puerto", 25 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 26 | "Select" : "Seleccionar", 27 | "Stream Length" : "Longitud del flujo", 28 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 29 | "bytes" : "bytes", 30 | "Path to clamscan" : "Ruta a clamscan", 31 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 32 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 33 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 34 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 35 | "Only log" : "Solo bitácora", 36 | "Delete file" : "Borrar archivo", 37 | "Save" : "Guardar", 38 | "Advanced" : "Avanzado", 39 | "Rules" : "Reglas", 40 | "Clear All" : "Limpiar todo", 41 | "Reset to defaults" : "Restablercer los valores predeterminados", 42 | "Match by" : "Coincidencia por", 43 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 44 | "Description" : "Descripción", 45 | "Mark as" : "Marcar como", 46 | "Add a rule" : "Agregar una regla" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_CR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Limpiar", 3 | "Infected" : "Infectado", 4 | "Unchecked" : "Desmarcado", 5 | "Scanner exit status" : "Estatus de salida del scanner", 6 | "Scanner output" : "Salida del scanner", 7 | "Saving…" : "Guardando...", 8 | "Antivirus" : "Antivirus", 9 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 10 | "The file has been removed" : "El archivo ha sido eliminado", 11 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 12 | "Antivirus detected a virus" : "El antivirus detectó un virus", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 14 | "Saved" : "Guardado", 15 | "Greetings {user}," : "Saludos {user},", 16 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 17 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 18 | "File uploaded: {file}" : "Archivo guardado: {file}", 19 | "Mode" : "Modo", 20 | "Socket" : "Socket", 21 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 22 | "Host" : "Servidor", 23 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 24 | "Port" : "Puerto", 25 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 26 | "Select" : "Seleccionar", 27 | "Stream Length" : "Longitud del flujo", 28 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 29 | "bytes" : "bytes", 30 | "Path to clamscan" : "Ruta a clamscan", 31 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 32 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 33 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 34 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 35 | "Only log" : "Solo bitácora", 36 | "Delete file" : "Borrar archivo", 37 | "Save" : "Guardar", 38 | "Advanced" : "Avanzado", 39 | "Rules" : "Reglas", 40 | "Clear All" : "Limpiar todo", 41 | "Reset to defaults" : "Restablercer los valores predeterminados", 42 | "Match by" : "Coincidencia por", 43 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 44 | "Description" : "Descripción", 45 | "Mark as" : "Marcar como", 46 | "Add a rule" : "Agregar una regla" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_DO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Limpiar", 3 | "Infected" : "Infectado", 4 | "Unchecked" : "Desmarcado", 5 | "Scanner exit status" : "Estatus de salida del scanner", 6 | "Scanner output" : "Salida del scanner", 7 | "Saving…" : "Guardando...", 8 | "Antivirus" : "Antivirus", 9 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 10 | "The file has been removed" : "El archivo ha sido eliminado", 11 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 12 | "Antivirus detected a virus" : "El antivirus detectó un virus", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 14 | "Saved" : "Guardado", 15 | "Greetings {user}," : "Saludos {user},", 16 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 17 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 18 | "File uploaded: {file}" : "Archivo guardado: {file}", 19 | "Mode" : "Modo", 20 | "Socket" : "Socket", 21 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 22 | "Host" : "Servidor", 23 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 24 | "Port" : "Puerto", 25 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 26 | "Select" : "Seleccionar", 27 | "Stream Length" : "Longitud del flujo", 28 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 29 | "bytes" : "bytes", 30 | "Path to clamscan" : "Ruta a clamscan", 31 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 32 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 33 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 34 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 35 | "Only log" : "Solo bitácora", 36 | "Delete file" : "Borrar archivo", 37 | "Save" : "Guardar", 38 | "Advanced" : "Avanzado", 39 | "Rules" : "Reglas", 40 | "Clear All" : "Limpiar todo", 41 | "Reset to defaults" : "Restablercer los valores predeterminados", 42 | "Match by" : "Coincidencia por", 43 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 44 | "Description" : "Descripción", 45 | "Mark as" : "Marcar como", 46 | "Add a rule" : "Agregar una regla" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_GT.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Limpiar", 3 | "Infected" : "Infectado", 4 | "Unchecked" : "Desmarcado", 5 | "Scanner exit status" : "Estatus de salida del scanner", 6 | "Scanner output" : "Salida del scanner", 7 | "Saving…" : "Guardando...", 8 | "Antivirus" : "Antivirus", 9 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 10 | "The file has been removed" : "El archivo ha sido eliminado", 11 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 12 | "Antivirus detected a virus" : "El antivirus detectó un virus", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 14 | "Saved" : "Guardado", 15 | "Greetings {user}," : "Saludos {user},", 16 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 17 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 18 | "File uploaded: {file}" : "Archivo guardado: {file}", 19 | "Mode" : "Modo", 20 | "Socket" : "Socket", 21 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 22 | "Host" : "Servidor", 23 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 24 | "Port" : "Puerto", 25 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 26 | "Select" : "Seleccionar", 27 | "Stream Length" : "Longitud del flujo", 28 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 29 | "bytes" : "bytes", 30 | "Path to clamscan" : "Ruta a clamscan", 31 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 32 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 33 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 34 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 35 | "Only log" : "Solo bitácora", 36 | "Delete file" : "Borrar archivo", 37 | "Save" : "Guardar", 38 | "Advanced" : "Avanzado", 39 | "Rules" : "Reglas", 40 | "Clear All" : "Limpiar todo", 41 | "Reset to defaults" : "Restablercer los valores predeterminados", 42 | "Match by" : "Coincidencia por", 43 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 44 | "Description" : "Descripción", 45 | "Mark as" : "Marcar como", 46 | "Add a rule" : "Agregar una regla" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_HN.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Limpiar", 3 | "Infected" : "Infectado", 4 | "Unchecked" : "Desmarcado", 5 | "Scanner exit status" : "Estatus de salida del scanner", 6 | "Scanner output" : "Salida del scanner", 7 | "Saving…" : "Guardando...", 8 | "Antivirus" : "Antivirus", 9 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 10 | "The file has been removed" : "El archivo ha sido eliminado", 11 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 12 | "Antivirus detected a virus" : "El antivirus detectó un virus", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 14 | "Saved" : "Guardado", 15 | "Greetings {user}," : "Saludos {user},", 16 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 17 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 18 | "File uploaded: {file}" : "Archivo guardado: {file}", 19 | "Mode" : "Modo", 20 | "Socket" : "Socket", 21 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 22 | "Host" : "Servidor", 23 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 24 | "Port" : "Puerto", 25 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 26 | "Select" : "Seleccionar", 27 | "Stream Length" : "Longitud del flujo", 28 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 29 | "bytes" : "bytes", 30 | "Path to clamscan" : "Ruta a clamscan", 31 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 32 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 33 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 34 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 35 | "Only log" : "Solo bitácora", 36 | "Delete file" : "Borrar archivo", 37 | "Save" : "Guardar", 38 | "Advanced" : "Avanzado", 39 | "Rules" : "Reglas", 40 | "Clear All" : "Limpiar todo", 41 | "Reset to defaults" : "Restablercer los valores predeterminados", 42 | "Match by" : "Coincidencia por", 43 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 44 | "Description" : "Descripción", 45 | "Mark as" : "Marcar como", 46 | "Add a rule" : "Agregar una regla" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_SV.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Limpiar", 3 | "Infected" : "Infectado", 4 | "Unchecked" : "Desmarcado", 5 | "Scanner exit status" : "Estatus de salida del scanner", 6 | "Scanner output" : "Salida del scanner", 7 | "Saving…" : "Guardando...", 8 | "Antivirus" : "Antivirus", 9 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 10 | "The file has been removed" : "El archivo ha sido eliminado", 11 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 12 | "Antivirus detected a virus" : "El antivirus detectó un virus", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 14 | "Saved" : "Guardado", 15 | "Greetings {user}," : "Saludos {user},", 16 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 17 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 18 | "File uploaded: {file}" : "Archivo guardado: {file}", 19 | "Mode" : "Modo", 20 | "Socket" : "Socket", 21 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 22 | "Host" : "Servidor", 23 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 24 | "Port" : "Puerto", 25 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 26 | "Select" : "Seleccionar", 27 | "Stream Length" : "Longitud del flujo", 28 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 29 | "bytes" : "bytes", 30 | "Path to clamscan" : "Ruta a clamscan", 31 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 32 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 33 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 34 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 35 | "Only log" : "Solo bitácora", 36 | "Delete file" : "Borrar archivo", 37 | "Save" : "Guardar", 38 | "Advanced" : "Avanzado", 39 | "Rules" : "Reglas", 40 | "Clear All" : "Limpiar todo", 41 | "Reset to defaults" : "Restablercer los valores predeterminados", 42 | "Match by" : "Coincidencia por", 43 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 44 | "Description" : "Descripción", 45 | "Mark as" : "Marcar como", 46 | "Add a rule" : "Agregar una regla" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/is.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Hreint", 5 | "Infected" : "Smitað", 6 | "Unchecked" : "Ekki skoðað", 7 | "Scanner exit status" : "Staða skanna þegar hætt var", 8 | "Scanner output" : "Úttak skanna", 9 | "Saving…" : "Vista…", 10 | "Antivirus" : "Vírusvörn", 11 | "File {file} is infected with {virus}" : "Skráin {file} er smituð af {virus}", 12 | "The file has been removed" : "Skráin var fjarlægð", 13 | "File containing {virus} detected" : "Fann skrá sem inniheldur {virus}", 14 | "Antivirus detected a virus" : "Vírusvörnin fann vírus", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Vírusinn %s finnst í skránni. Ekki er hægt að ljúka innsendingu.", 16 | "Saved" : "Vistað", 17 | "Antivirus for files" : "Vírusvarnarforrit fyrir skrár", 18 | "Greetings {user}," : "Daginn {user},", 19 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Því miður, en það fannst spillifarmur í skrá sem þú varst að reyna að senda inn og því þurfti að eyða henni.", 20 | "This email is a notification from {host}. Please, do not reply." : "Þessi tölvupóstur er tilkynning frá {host}. Ekki svara honum.", 21 | "File uploaded: {file}" : "Innsend skrá: {file}", 22 | "Antivirus for Files" : "Vírusvarnarforrit fyrir skrár", 23 | "Mode" : "Hamur", 24 | "Socket" : "Rafmagnsinnstunga", 25 | "Not required in Executable Mode." : "Ekki nauðsynlegt í keyrsluham.", 26 | "Host" : "Netþjónn", 27 | "Address of Antivirus Host." : "Vistfang vírusvarnavélar.", 28 | "Port" : "Gátt", 29 | "Port number of Antivirus Host." : "Gáttarnúmer vírusvarnavélar.", 30 | "TLS" : "TLS", 31 | "Select" : "Velja", 32 | "Stream Length" : "Lengd streymis", 33 | "ClamAV StreamMaxLength value in bytes." : "Gildi ClamAV StreamMaxLength í bætum.", 34 | "bytes" : "bæti", 35 | "Path to clamscan" : "Slóð að clamscan", 36 | "Path to clamscan executable." : "Slóð að clamscan-keyrsluskránni.", 37 | "Not required in Daemon Mode." : "Ekki nauðsynlegt í púkaham.", 38 | "Extra command line options (comma-separated)" : "Auka skipanalínurofar (aðskilið með kommu)", 39 | "When infected files are found during a background scan" : "Þegar smitaðar skrár finnast við bakgrunnsskönnun", 40 | "Only log" : "Aðeins skrá í annál", 41 | "Delete file" : "Eyða skrá", 42 | "Save" : "Vista", 43 | "Advanced" : "Ítarlegt", 44 | "Rules" : "Reglur", 45 | "Clear All" : "Hreinsa allt", 46 | "Reset to defaults" : "Frumstilla á sjálfgefin gildi", 47 | "Match by" : "Samsvara", 48 | "Scanner exit status or signature to search" : "Staða skanna þegar hætt er eða auðkenni (signature) til að leita eftir", 49 | "Description" : "Lýsing", 50 | "Mark as" : "Merkja sem", 51 | "Add a rule" : "Bæta við reglu" 52 | }, 53 | "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); 54 | -------------------------------------------------------------------------------- /l10n/es_CL.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Limpiar", 3 | "Infected" : "Infectado", 4 | "Unchecked" : "Desmarcado", 5 | "Scanner exit status" : "Estatus de salida del scanner", 6 | "Scanner output" : "Salida del scanner", 7 | "Saving…" : "Guardando...", 8 | "Antivirus" : "Antivirus", 9 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 10 | "The file has been removed" : "El archivo ha sido eliminado", 11 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 12 | "Antivirus detected a virus" : "El antivirus detectó un virus", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 14 | "Saved" : "Guardado", 15 | "Greetings {user}," : "Saludos {user},", 16 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 17 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 18 | "File uploaded: {file}" : "Archivo guardado: {file}", 19 | "Mode" : "Modo", 20 | "Socket" : "Socket", 21 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 22 | "Host" : "Servidor", 23 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 24 | "Port" : "Puerto", 25 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 26 | "Select" : "Seleccionar", 27 | "Stream Length" : "Longitud del flujo", 28 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 29 | "bytes" : "bytes", 30 | "Path to clamscan" : "Ruta a clamscan", 31 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 32 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 33 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 34 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 35 | "Only log" : "Solo bitácora", 36 | "Delete file" : "Borrar archivo", 37 | "Yes" : "Si", 38 | "Save" : "Guardar", 39 | "Advanced" : "Avanzado", 40 | "Rules" : "Reglas", 41 | "Clear All" : "Limpiar todo", 42 | "Reset to defaults" : "Restablercer los valores predeterminados", 43 | "Match by" : "Coincidencia por", 44 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 45 | "Description" : "Descripción", 46 | "Mark as" : "Marcar como", 47 | "Add a rule" : "Agregar una regla" 48 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 49 | } -------------------------------------------------------------------------------- /l10n/es_CO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Limpiar", 5 | "Infected" : "Infectado", 6 | "Unchecked" : "Desmarcado", 7 | "Scanner exit status" : "Estatus de salida del scanner", 8 | "Scanner output" : "Salida del scanner", 9 | "Saving…" : "Guardando...", 10 | "Antivirus" : "Antivirus", 11 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 12 | "The file has been removed" : "El archivo ha sido eliminado", 13 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 14 | "Antivirus detected a virus" : "El antivirus detectó un virus", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 16 | "Saved" : "Guardado", 17 | "Greetings {user}," : "Saludos {user},", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 19 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 20 | "File uploaded: {file}" : "Archivo guardado: {file}", 21 | "Mode" : "Modo", 22 | "Socket" : "Socket", 23 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 24 | "Host" : "Servidor", 25 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 26 | "Port" : "Puerto", 27 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 28 | "Select" : "Seleccionar", 29 | "Stream Length" : "Longitud del flujo", 30 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 31 | "bytes" : "bytes", 32 | "Path to clamscan" : "Ruta a clamscan", 33 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 34 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 35 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 36 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 37 | "Only log" : "Solo bitácora", 38 | "Delete file" : "Borrar archivo", 39 | "Save" : "Guardar", 40 | "Advanced" : "Avanzado", 41 | "Rules" : "Reglas", 42 | "Clear All" : "Limpiar todo", 43 | "Reset to defaults" : "Restablercer los valores predeterminados", 44 | "Match by" : "Coincidencia por", 45 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 46 | "Description" : "Descripción", 47 | "Mark as" : "Marcar como", 48 | "Add a rule" : "Agregar una regla" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_CR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Limpiar", 5 | "Infected" : "Infectado", 6 | "Unchecked" : "Desmarcado", 7 | "Scanner exit status" : "Estatus de salida del scanner", 8 | "Scanner output" : "Salida del scanner", 9 | "Saving…" : "Guardando...", 10 | "Antivirus" : "Antivirus", 11 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 12 | "The file has been removed" : "El archivo ha sido eliminado", 13 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 14 | "Antivirus detected a virus" : "El antivirus detectó un virus", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 16 | "Saved" : "Guardado", 17 | "Greetings {user}," : "Saludos {user},", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 19 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 20 | "File uploaded: {file}" : "Archivo guardado: {file}", 21 | "Mode" : "Modo", 22 | "Socket" : "Socket", 23 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 24 | "Host" : "Servidor", 25 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 26 | "Port" : "Puerto", 27 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 28 | "Select" : "Seleccionar", 29 | "Stream Length" : "Longitud del flujo", 30 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 31 | "bytes" : "bytes", 32 | "Path to clamscan" : "Ruta a clamscan", 33 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 34 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 35 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 36 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 37 | "Only log" : "Solo bitácora", 38 | "Delete file" : "Borrar archivo", 39 | "Save" : "Guardar", 40 | "Advanced" : "Avanzado", 41 | "Rules" : "Reglas", 42 | "Clear All" : "Limpiar todo", 43 | "Reset to defaults" : "Restablercer los valores predeterminados", 44 | "Match by" : "Coincidencia por", 45 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 46 | "Description" : "Descripción", 47 | "Mark as" : "Marcar como", 48 | "Add a rule" : "Agregar una regla" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_DO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Limpiar", 5 | "Infected" : "Infectado", 6 | "Unchecked" : "Desmarcado", 7 | "Scanner exit status" : "Estatus de salida del scanner", 8 | "Scanner output" : "Salida del scanner", 9 | "Saving…" : "Guardando...", 10 | "Antivirus" : "Antivirus", 11 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 12 | "The file has been removed" : "El archivo ha sido eliminado", 13 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 14 | "Antivirus detected a virus" : "El antivirus detectó un virus", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 16 | "Saved" : "Guardado", 17 | "Greetings {user}," : "Saludos {user},", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 19 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 20 | "File uploaded: {file}" : "Archivo guardado: {file}", 21 | "Mode" : "Modo", 22 | "Socket" : "Socket", 23 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 24 | "Host" : "Servidor", 25 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 26 | "Port" : "Puerto", 27 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 28 | "Select" : "Seleccionar", 29 | "Stream Length" : "Longitud del flujo", 30 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 31 | "bytes" : "bytes", 32 | "Path to clamscan" : "Ruta a clamscan", 33 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 34 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 35 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 36 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 37 | "Only log" : "Solo bitácora", 38 | "Delete file" : "Borrar archivo", 39 | "Save" : "Guardar", 40 | "Advanced" : "Avanzado", 41 | "Rules" : "Reglas", 42 | "Clear All" : "Limpiar todo", 43 | "Reset to defaults" : "Restablercer los valores predeterminados", 44 | "Match by" : "Coincidencia por", 45 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 46 | "Description" : "Descripción", 47 | "Mark as" : "Marcar como", 48 | "Add a rule" : "Agregar una regla" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_GT.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Limpiar", 5 | "Infected" : "Infectado", 6 | "Unchecked" : "Desmarcado", 7 | "Scanner exit status" : "Estatus de salida del scanner", 8 | "Scanner output" : "Salida del scanner", 9 | "Saving…" : "Guardando...", 10 | "Antivirus" : "Antivirus", 11 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 12 | "The file has been removed" : "El archivo ha sido eliminado", 13 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 14 | "Antivirus detected a virus" : "El antivirus detectó un virus", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 16 | "Saved" : "Guardado", 17 | "Greetings {user}," : "Saludos {user},", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 19 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 20 | "File uploaded: {file}" : "Archivo guardado: {file}", 21 | "Mode" : "Modo", 22 | "Socket" : "Socket", 23 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 24 | "Host" : "Servidor", 25 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 26 | "Port" : "Puerto", 27 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 28 | "Select" : "Seleccionar", 29 | "Stream Length" : "Longitud del flujo", 30 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 31 | "bytes" : "bytes", 32 | "Path to clamscan" : "Ruta a clamscan", 33 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 34 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 35 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 36 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 37 | "Only log" : "Solo bitácora", 38 | "Delete file" : "Borrar archivo", 39 | "Save" : "Guardar", 40 | "Advanced" : "Avanzado", 41 | "Rules" : "Reglas", 42 | "Clear All" : "Limpiar todo", 43 | "Reset to defaults" : "Restablercer los valores predeterminados", 44 | "Match by" : "Coincidencia por", 45 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 46 | "Description" : "Descripción", 47 | "Mark as" : "Marcar como", 48 | "Add a rule" : "Agregar una regla" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_HN.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Limpiar", 5 | "Infected" : "Infectado", 6 | "Unchecked" : "Desmarcado", 7 | "Scanner exit status" : "Estatus de salida del scanner", 8 | "Scanner output" : "Salida del scanner", 9 | "Saving…" : "Guardando...", 10 | "Antivirus" : "Antivirus", 11 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 12 | "The file has been removed" : "El archivo ha sido eliminado", 13 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 14 | "Antivirus detected a virus" : "El antivirus detectó un virus", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 16 | "Saved" : "Guardado", 17 | "Greetings {user}," : "Saludos {user},", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 19 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 20 | "File uploaded: {file}" : "Archivo guardado: {file}", 21 | "Mode" : "Modo", 22 | "Socket" : "Socket", 23 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 24 | "Host" : "Servidor", 25 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 26 | "Port" : "Puerto", 27 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 28 | "Select" : "Seleccionar", 29 | "Stream Length" : "Longitud del flujo", 30 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 31 | "bytes" : "bytes", 32 | "Path to clamscan" : "Ruta a clamscan", 33 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 34 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 35 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 36 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 37 | "Only log" : "Solo bitácora", 38 | "Delete file" : "Borrar archivo", 39 | "Save" : "Guardar", 40 | "Advanced" : "Avanzado", 41 | "Rules" : "Reglas", 42 | "Clear All" : "Limpiar todo", 43 | "Reset to defaults" : "Restablercer los valores predeterminados", 44 | "Match by" : "Coincidencia por", 45 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 46 | "Description" : "Descripción", 47 | "Mark as" : "Marcar como", 48 | "Add a rule" : "Agregar una regla" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_SV.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Limpiar", 5 | "Infected" : "Infectado", 6 | "Unchecked" : "Desmarcado", 7 | "Scanner exit status" : "Estatus de salida del scanner", 8 | "Scanner output" : "Salida del scanner", 9 | "Saving…" : "Guardando...", 10 | "Antivirus" : "Antivirus", 11 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 12 | "The file has been removed" : "El archivo ha sido eliminado", 13 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 14 | "Antivirus detected a virus" : "El antivirus detectó un virus", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 16 | "Saved" : "Guardado", 17 | "Greetings {user}," : "Saludos {user},", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 19 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 20 | "File uploaded: {file}" : "Archivo guardado: {file}", 21 | "Mode" : "Modo", 22 | "Socket" : "Socket", 23 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 24 | "Host" : "Servidor", 25 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 26 | "Port" : "Puerto", 27 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 28 | "Select" : "Seleccionar", 29 | "Stream Length" : "Longitud del flujo", 30 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 31 | "bytes" : "bytes", 32 | "Path to clamscan" : "Ruta a clamscan", 33 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 34 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 35 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 36 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 37 | "Only log" : "Solo bitácora", 38 | "Delete file" : "Borrar archivo", 39 | "Save" : "Guardar", 40 | "Advanced" : "Avanzado", 41 | "Rules" : "Reglas", 42 | "Clear All" : "Limpiar todo", 43 | "Reset to defaults" : "Restablercer los valores predeterminados", 44 | "Match by" : "Coincidencia por", 45 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 46 | "Description" : "Descripción", 47 | "Mark as" : "Marcar como", 48 | "Add a rule" : "Agregar una regla" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_CL.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Limpiar", 5 | "Infected" : "Infectado", 6 | "Unchecked" : "Desmarcado", 7 | "Scanner exit status" : "Estatus de salida del scanner", 8 | "Scanner output" : "Salida del scanner", 9 | "Saving…" : "Guardando...", 10 | "Antivirus" : "Antivirus", 11 | "File {file} is infected with {virus}" : "El archivo {file} está infectado con {virus}", 12 | "The file has been removed" : "El archivo ha sido eliminado", 13 | "File containing {virus} detected" : "Se ha detectado un que archivo que contiene {virus}", 14 | "Antivirus detected a virus" : "El antivirus detectó un virus", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Se detectó el virus %s en el archivo. La carga no puede ser completada.", 16 | "Saved" : "Guardado", 17 | "Greetings {user}," : "Saludos {user},", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Lo sentimos, pero se ha detectado un malware en el archivo que intentabas cargar y tuvo que ser borrado.", 19 | "This email is a notification from {host}. Please, do not reply." : "Esta es una notificación de {host}. Por favor, no respondas. ", 20 | "File uploaded: {file}" : "Archivo guardado: {file}", 21 | "Mode" : "Modo", 22 | "Socket" : "Socket", 23 | "Not required in Executable Mode." : "No requerido en Modo Ejecutable.", 24 | "Host" : "Servidor", 25 | "Address of Antivirus Host." : "Dirección del Servidor de Antivirus.", 26 | "Port" : "Puerto", 27 | "Port number of Antivirus Host." : "Número de puerto del Servidor de Antivirus.", 28 | "Select" : "Seleccionar", 29 | "Stream Length" : "Longitud del flujo", 30 | "ClamAV StreamMaxLength value in bytes." : "Valor en bytes de ClamAV StreamMaxLength.", 31 | "bytes" : "bytes", 32 | "Path to clamscan" : "Ruta a clamscan", 33 | "Path to clamscan executable." : "Ruta al ejecutable de clamscan.", 34 | "Not required in Daemon Mode." : "No requerido en modo demonio.", 35 | "Extra command line options (comma-separated)" : "Opciones adicionales de la línea de comandos (separados por coma)", 36 | "When infected files are found during a background scan" : "Cuando se encuentres archivos infectados durante un escaneo en segundo plano", 37 | "Only log" : "Solo bitácora", 38 | "Delete file" : "Borrar archivo", 39 | "Yes" : "Si", 40 | "Save" : "Guardar", 41 | "Advanced" : "Avanzado", 42 | "Rules" : "Reglas", 43 | "Clear All" : "Limpiar todo", 44 | "Reset to defaults" : "Restablercer los valores predeterminados", 45 | "Match by" : "Coincidencia por", 46 | "Scanner exit status or signature to search" : "Estatus de salida del escaner o firma a buscar", 47 | "Description" : "Descripción", 48 | "Mark as" : "Marcar como", 49 | "Add a rule" : "Agregar una regla" 50 | }, 51 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 52 | -------------------------------------------------------------------------------- /l10n/sv.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "Rensa", 3 | "Infected" : "Infekterad", 4 | "Unchecked" : "Avmarkerade", 5 | "Scanner exit status" : "Skannerns avslutningsstatus", 6 | "Scanner output" : "Skannerutdata", 7 | "Saving…" : "Sparar ...", 8 | "Antivirus" : "Antivirus", 9 | "File {file} is infected with {virus}" : "Filen {file} är infekterad med {virus}", 10 | "The file has been removed" : "Filen har tagits bort", 11 | "File containing {virus} detected" : "Fil innehållande {virus} upptäckt", 12 | "Antivirus detected a virus" : "Antivirus upptäckte ett virus", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "Virus %s upptäcks i filen. Uppladdningen kan inte slutföras.", 14 | "Saved" : "Sparad", 15 | "Antivirus for files" : "Antivirus för filer", 16 | "An antivirus app for Nextcloud" : "En antivirusapp för Nextcloud", 17 | "Greetings {user}," : "Hälsningar {user},", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Tyvärr, men en skadlig kod upptäcktes i en fil som du försökte ladda upp och det måste tas bort.", 19 | "This email is a notification from {host}. Please, do not reply." : "Det här e-postmeddelandet är ett meddelande från {host}. Snälla, svara inte.", 20 | "File uploaded: {file}" : "Fil skickad: {file}", 21 | "Antivirus for Files" : "Antivirus för filer", 22 | "Mode" : "Läge", 23 | "Socket" : "Socket", 24 | "Not required in Executable Mode." : "Krävs inte i körbart läge.", 25 | "Host" : "Värd", 26 | "Address of Antivirus Host." : "Adress för antivirus-värd.", 27 | "Port" : "Port", 28 | "Port number of Antivirus Host." : "Portnummer för Antivirus Host.", 29 | "TLS" : "TLS", 30 | "Select" : "Välj", 31 | "Stream Length" : "Strömlängd", 32 | "ClamAV StreamMaxLength value in bytes." : "ClamAV StreamMaxLength-värde i byte.", 33 | "bytes" : "byte", 34 | "Path to clamscan" : "Sökväg till clamscan", 35 | "Path to clamscan executable." : "Sökväg till körbara clamscan.", 36 | "Not required in Daemon Mode." : "Krävs inte i Demon-läge.", 37 | "Extra command line options (comma-separated)" : "Extra kommandoradsalternativ (kommaseparerade)", 38 | "When infected files are found during a background scan" : "När infekterade filer hittas under en bakgrundssökning", 39 | "Only log" : "Logga endast", 40 | "Delete file" : "Ta bort fil", 41 | "Yes" : "Ja", 42 | "No" : "Nej", 43 | "Save" : "Spara", 44 | "Advanced" : "Avancerat", 45 | "Rules" : "Regler", 46 | "Clear All" : "Rensa alla", 47 | "Reset to defaults" : "Återställ till standardvärden", 48 | "Match by" : "Matchning efter", 49 | "Scanner exit status or signature to search" : "Skannerens avslutningsstatus eller signatur för att söka", 50 | "Description" : "Beskrivning", 51 | "Mark as" : "Märk som", 52 | "Add a rule" : "Lägg till en regel" 53 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 54 | } -------------------------------------------------------------------------------- /l10n/sv.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_antivirus", 3 | { 4 | "Clean" : "Rensa", 5 | "Infected" : "Infekterad", 6 | "Unchecked" : "Avmarkerade", 7 | "Scanner exit status" : "Skannerns avslutningsstatus", 8 | "Scanner output" : "Skannerutdata", 9 | "Saving…" : "Sparar ...", 10 | "Antivirus" : "Antivirus", 11 | "File {file} is infected with {virus}" : "Filen {file} är infekterad med {virus}", 12 | "The file has been removed" : "Filen har tagits bort", 13 | "File containing {virus} detected" : "Fil innehållande {virus} upptäckt", 14 | "Antivirus detected a virus" : "Antivirus upptäckte ett virus", 15 | "Virus %s is detected in the file. Upload cannot be completed." : "Virus %s upptäcks i filen. Uppladdningen kan inte slutföras.", 16 | "Saved" : "Sparad", 17 | "Antivirus for files" : "Antivirus för filer", 18 | "An antivirus app for Nextcloud" : "En antivirusapp för Nextcloud", 19 | "Greetings {user}," : "Hälsningar {user},", 20 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "Tyvärr, men en skadlig kod upptäcktes i en fil som du försökte ladda upp och det måste tas bort.", 21 | "This email is a notification from {host}. Please, do not reply." : "Det här e-postmeddelandet är ett meddelande från {host}. Snälla, svara inte.", 22 | "File uploaded: {file}" : "Fil skickad: {file}", 23 | "Antivirus for Files" : "Antivirus för filer", 24 | "Mode" : "Läge", 25 | "Socket" : "Socket", 26 | "Not required in Executable Mode." : "Krävs inte i körbart läge.", 27 | "Host" : "Värd", 28 | "Address of Antivirus Host." : "Adress för antivirus-värd.", 29 | "Port" : "Port", 30 | "Port number of Antivirus Host." : "Portnummer för Antivirus Host.", 31 | "TLS" : "TLS", 32 | "Select" : "Välj", 33 | "Stream Length" : "Strömlängd", 34 | "ClamAV StreamMaxLength value in bytes." : "ClamAV StreamMaxLength-värde i byte.", 35 | "bytes" : "byte", 36 | "Path to clamscan" : "Sökväg till clamscan", 37 | "Path to clamscan executable." : "Sökväg till körbara clamscan.", 38 | "Not required in Daemon Mode." : "Krävs inte i Demon-läge.", 39 | "Extra command line options (comma-separated)" : "Extra kommandoradsalternativ (kommaseparerade)", 40 | "When infected files are found during a background scan" : "När infekterade filer hittas under en bakgrundssökning", 41 | "Only log" : "Logga endast", 42 | "Delete file" : "Ta bort fil", 43 | "Yes" : "Ja", 44 | "No" : "Nej", 45 | "Save" : "Spara", 46 | "Advanced" : "Avancerat", 47 | "Rules" : "Regler", 48 | "Clear All" : "Rensa alla", 49 | "Reset to defaults" : "Återställ till standardvärden", 50 | "Match by" : "Matchning efter", 51 | "Scanner exit status or signature to search" : "Skannerens avslutningsstatus eller signatur för att söka", 52 | "Description" : "Beskrivning", 53 | "Mark as" : "Märk som", 54 | "Add a rule" : "Lägg till en regel" 55 | }, 56 | "nplurals=2; plural=(n != 1);"); 57 | -------------------------------------------------------------------------------- /l10n/he.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Clean" : "ניקוי", 3 | "Infected" : "נגוע", 4 | "Unchecked" : "לא נבדק", 5 | "Scanner exit status" : "מצב היציאה של הסורק", 6 | "Scanner output" : "פלט הסורק", 7 | "Saving…" : "מתבצעת שמירה…", 8 | "Antivirus" : "אנטיוירוס", 9 | "File {file} is infected with {virus}" : "הקובץ {file} נגוע בווירוס {virus}", 10 | "The file has been removed" : "הקובץ הוסר", 11 | "File containing {virus} detected" : "זוהה קובץ שמכיל את {virus}", 12 | "Antivirus detected a virus" : "האנטיוירוס זיהה וירוס", 13 | "Virus %s is detected in the file. Upload cannot be completed." : "התגלה וירוס %s בקובץ. לא ניתן להשלים את ההלאה.", 14 | "Saved" : "נשמר", 15 | "Antivirus for files" : "אנטיוירוס לקבצים", 16 | "An antivirus app for Nextcloud" : "יישומון אנטיוירוס ל־Nextcloud", 17 | "Greetings {user}," : "ברכות {user},", 18 | "Sorry, but a malware was detected in a file you tried to upload and it had to be deleted." : "התגלתה נוזקה בקובץ שניסית להעלות ולכן הוא נמחק, עמך הסליחה.", 19 | "This email is a notification from {host}. Please, do not reply." : "הודעת דוא״ל זאת היא מאת {host}. נא לא להגיב.", 20 | "File uploaded: {file}" : "קובץ הועלה: {file}", 21 | "Antivirus for Files" : "אנטיוירוס לקבצים", 22 | "Mode" : "מצב", 23 | "ClamAV Executable" : "קובץ ההפעלה של ClamAV", 24 | "ClamAV Daemon" : "סוכן רקע של ClamAV", 25 | "ClamAV Daemon (Socket)" : "סוכן רקע של ClamAV (שקע - Socket)", 26 | "Kaspersky Daemon" : "סוכן רקע של Kaspersky", 27 | "Socket" : "שקע", 28 | "ClamAV Socket." : "שקע - Socket של ClamAV.", 29 | "Not required in Executable Mode." : "לא נדרש במצב הפעלה.", 30 | "Host" : "מארח", 31 | "Address of Antivirus Host." : "כתובת מארח האנטיוירוס.", 32 | "Port" : "פתחה", 33 | "Port number of Antivirus Host." : "מספר הפתחה של מארח האנטיוירוס.", 34 | "TLS" : "TLS", 35 | "Select" : "בחירה", 36 | "Stream Length" : "אורך התזרים", 37 | "ClamAV StreamMaxLength value in bytes." : "ערך StreamMaxLength של ClamAV בבתים.", 38 | "bytes" : "בתים", 39 | "Path to clamscan" : "נתיב אל clamscan", 40 | "Path to clamscan executable." : "נתיב אל קובץ ההפעלה של clamscan.", 41 | "Not required in Daemon Mode." : "לא נדרש במצב סוכן", 42 | "Extra command line options (comma-separated)" : "אפשרויות נוספות לשורת הפקודה (בהפרדה לפסיקים)", 43 | "When infected files are found during a background scan" : "כאשר נמצאים קבצים נגועים במהלך סריקת רגע", 44 | "Only log" : "לתעד בלבד", 45 | "Delete file" : "מחיקת קובץ", 46 | "Save" : "שמירה", 47 | "Advanced" : "מתקדם", 48 | "Rules" : "כללים", 49 | "Clear All" : "לפנות הכול", 50 | "Reset to defaults" : "איפוס לבררת המחדל", 51 | "Match by" : "התאמה לפי", 52 | "Scanner exit status or signature to search" : "מצב יציאה של סורק או חתימה לחיפוש", 53 | "Description" : "תיאור", 54 | "Mark as" : "סימון בתור", 55 | "Add a rule" : "הוספת כל" 56 | },"pluralForm" :"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;" 57 | } --------------------------------------------------------------------------------