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 | }
--------------------------------------------------------------------------------