Passed
Push — master ( ac48a9...31bd7d )
by Roeland
11:49
created
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Artem Sidorenko <[email protected]>
6
 * @author Bernhard Posselt <[email protected]>
7
 * @author Christopher Schäpers <[email protected]>
8
 * @author Damjan Georgievski <[email protected]>
9
 * @author Jakob Sack <[email protected]>
10
 * @author Joas Schilling <[email protected]>
11
 * @author Jörn Friedrich Dreyer <[email protected]>
12
 * @author Ko- <[email protected]>
13
 * @author Morris Jobke <[email protected]>
14
 * @author Oliver Kohl D.Sc. <[email protected]>
15
 * @author Robin Appelman <[email protected]>
16
 * @author Roeland Jago Douma <[email protected]>
17
 * @author Steffen Lindner <[email protected]>
18
 * @author Thomas Müller <[email protected]>
19
 * @author Vincent Petry <[email protected]>
20
 *
21
 * @license AGPL-3.0
22
 *
23
 * This code is free software: you can redistribute it and/or modify
24
 * it under the terms of the GNU Affero General Public License, version 3,
25
 * as published by the Free Software Foundation.
26
 *
27
 * This program is distributed in the hope that it will be useful,
28
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
 * GNU Affero General Public License for more details.
31
 *
32
 * You should have received a copy of the GNU Affero General Public License, version 3,
33
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
34
 *
35
 */
36
37
require_once __DIR__ . '/lib/versioncheck.php';
38
39
try {
40
41
	require_once __DIR__ . '/lib/base.php';
42
43
	if (\OCP\Util::needUpgrade()) {
44
		\OC::$server->getLogger()->debug('Update required, skipping cron', ['app' => 'cron']);
45
		exit;
46
	}
47
	if ((bool) \OC::$server->getSystemConfig()->getValue('maintenance', false)) {
48
		\OC::$server->getLogger()->debug('We are in maintenance mode, skipping cron', ['app' => 'cron']);
49
		exit;
50
	}
51
52
	// load all apps to get all api routes properly setup
53
	OC_App::loadApps();
54
55
	\OC::$server->getSession()->close();
56
57
	// initialize a dummy memory session
58
	$session = new \OC\Session\Memory('');
59
	$cryptoWrapper = \OC::$server->getSessionCryptoWrapper();
60
	$session = $cryptoWrapper->wrapSession($session);
61
	\OC::$server->setSession($session);
62
63
	$logger = \OC::$server->getLogger();
64
	$config = \OC::$server->getConfig();
65
66
	// Don't do anything if Nextcloud has not been installed
67
	if (!$config->getSystemValue('installed', false)) {
68
		exit(0);
69
	}
70
71
	\OC::$server->getTempManager()->cleanOld();
72
73
	// Exit if background jobs are disabled!
74
	$appMode = $config->getAppValue('core', 'backgroundjobs_mode', 'ajax');
75
	if ($appMode === 'none') {
76
		if (OC::$CLI) {
77
			echo 'Background Jobs are disabled!' . PHP_EOL;
78
		} else {
79
			OC_JSON::error(array('data' => array('message' => 'Background jobs disabled!')));
0 ignored issues
show
Deprecated Code introduced by
The function OC_JSON::error() has been deprecated: Use a AppFramework JSONResponse instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

79
			/** @scrutinizer ignore-deprecated */ OC_JSON::error(array('data' => array('message' => 'Background jobs disabled!')));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
80
		}
81
		exit(1);
82
	}
83
84
	if (OC::$CLI) {
85
		// set to run indefinitely if needed
86
		if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
87
			@set_time_limit(0);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for set_time_limit(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

87
			/** @scrutinizer ignore-unhandled */ @set_time_limit(0);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
88
		}
89
90
		// the cron job must be executed with the right user
91
		if (!function_exists('posix_getuid')) {
92
			echo "The posix extensions are required - see http://php.net/manual/en/book.posix.php" . PHP_EOL;
93
			exit(1);
94
		}
95
96
		$user = posix_getpwuid(posix_getuid());
97
		$configUser = posix_getpwuid(fileowner(OC::$configDir . 'config.php'));
98
		if ($user['name'] !== $configUser['name']) {
99
			echo "Console has to be executed with the user that owns the file config/config.php" . PHP_EOL;
100
			echo "Current user: " . $user['name'] . PHP_EOL;
101
			echo "Owner of config.php: " . $configUser['name'] . PHP_EOL;
102
			exit(1);
103
		}
104
105
		// We call Nextcloud from the CLI (aka cron)
106
		if ($appMode !== 'cron') {
107
			$config->setAppValue('core', 'backgroundjobs_mode', 'cron');
108
		}
109
110
		// Work
111
		$jobList = \OC::$server->getJobList();
112
113
		// We only ask for jobs for 14 minutes, because after 15 minutes the next
114
		// system cron task should spawn.
115
		$endTime = time() + 14 * 60;
116
117
		$executedJobs = [];
118
		while ($job = $jobList->getNext()) {
119
			if (isset($executedJobs[$job->getId()])) {
120
				$jobList->unlockJob($job);
121
				break;
122
			}
123
124
			$job->execute($jobList, $logger);
125
			// clean up after unclean jobs
126
			\OC_Util::tearDownFS();
127
128
			$jobList->setLastJob($job);
129
			$executedJobs[$job->getId()] = true;
130
			unset($job);
131
132
			if (time() > $endTime) {
133
				break;
134
			}
135
		}
136
137
	} else {
138
		// We call cron.php from some website
139
		if ($appMode === 'cron') {
140
			// Cron is cron :-P
141
			OC_JSON::error(array('data' => array('message' => 'Backgroundjobs are using system cron!')));
0 ignored issues
show
Deprecated Code introduced by
The function OC_JSON::error() has been deprecated: Use a AppFramework JSONResponse instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

141
			/** @scrutinizer ignore-deprecated */ OC_JSON::error(array('data' => array('message' => 'Backgroundjobs are using system cron!')));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
142
		} else {
143
			// Work and success :-)
144
			$jobList = \OC::$server->getJobList();
145
			$job = $jobList->getNext();
146
			if ($job != null) {
147
				$job->execute($jobList, $logger);
148
				$jobList->setLastJob($job);
149
			}
150
			OC_JSON::success();
0 ignored issues
show
Deprecated Code introduced by
The function OC_JSON::success() has been deprecated: Use a AppFramework JSONResponse instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

150
			/** @scrutinizer ignore-deprecated */ OC_JSON::success();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
151
		}
152
	}
153
154
	// Log the successful cron execution
155
	$config->setAppValue('core', 'lastcron', time());
156
	exit();
157
158
} catch (Exception $ex) {
159
	\OC::$server->getLogger()->logException($ex, ['app' => 'cron']);
160
} catch (Error $ex) {
161
	\OC::$server->getLogger()->logException($ex, ['app' => 'cron']);
162
}
163