Completed
Push — stable7 ( 35746e...825360 )
by
unknown
29:41
created

cron.php ➔ handleUnexpectedShutdown()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 15
Code Lines 8

Duplication

Lines 7
Ratio 46.67 %
Metric Value
cc 5
eloc 8
nc 6
nop 0
dl 7
loc 15
rs 8.8571
1
<?php
2
/**
3
 * ownCloud
4
 *
5
 * @author Jakob Sack
6
 * @copyright 2012 Jakob Sack [email protected]
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
10
 * License as published by the Free Software Foundation; either
11
 * version 3 of the License, or any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public
19
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
// Unfortunately we need this class for shutdown function
24
class TemporaryCronClass {
25
	public static $sent = false;
26
	public static $lockfile = "";
27
	public static $keeplock = false;
28
}
29
30
// We use this function to handle (unexpected) shutdowns
31
function handleUnexpectedShutdown() {
32
	// Delete lockfile
33
	if (!TemporaryCronClass::$keeplock && file_exists(TemporaryCronClass::$lockfile)) {
34
		unlink(TemporaryCronClass::$lockfile);
35
	}
36
37
	// Say goodbye if the app did not shutdown properly
38 View Code Duplication
	if (!TemporaryCronClass::$sent) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
39
		if (OC::$CLI) {
40
			echo 'Unexpected error!' . PHP_EOL;
41
		} else {
42
			OC_JSON::error(array('data' => array('message' => 'Unexpected error!')));
43
		}
44
	}
45
}
46
47
try {
48
49
	require_once 'lib/base.php';
50
51
	if (\OCP\Util::needUpgrade()) {
52
		\OCP\Util::writeLog('cron', 'Update required, skipping cron', \OCP\Util::DEBUG);
53
		exit;
54
	}
55
	if (\OC_Config::getValue('maintenance', false)) {
56
		\OCP\Util::writeLog('cron', 'We are in maintenance mode, skipping cron', \OCP\Util::DEBUG);
57
		exit;
58
	}
59
60
	if (\OCP\Config::getSystemValue('singleuser', false)) {
61
		\OCP\Util::writeLog('cron', 'We are in admin only mode, skipping cron', \OCP\Util::DEBUG);
62
		exit;
63
	}
64
65
	// load all apps to get all api routes properly setup
66
	OC_App::loadApps();
67
68
	\OC::$session->close();
69
70
	// initialize a dummy memory session
71
	\OC::$session = new \OC\Session\Memory('');
72
73
	$logger = \OC_Log::$object;
74
75
	// Don't do anything if ownCloud has not been installed
76
	if (!OC_Config::getValue('installed', false)) {
77
		exit(0);
78
	}
79
80
	// Handle unexpected errors
81
	register_shutdown_function('handleUnexpectedShutdown');
82
83
	\OC::$server->getTempManager()->cleanOld();
84
85
	// Exit if background jobs are disabled!
86
	$appmode = OC_BackgroundJob::getExecutionType();
87
	if ($appmode == 'none') {
88
		TemporaryCronClass::$sent = true;
89 View Code Duplication
		if (OC::$CLI) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
90
			echo 'Background Jobs are disabled!' . PHP_EOL;
91
		} else {
92
			OC_JSON::error(array('data' => array('message' => 'Background jobs disabled!')));
93
		}
94
		exit(1);
95
	}
96
97
	if (OC::$CLI) {
98
		// the cron job must be executed with the right user
99
		if (!OC_Util::runningOnWindows())  {
100
			if (!function_exists('posix_getuid')) {
101
				echo "The posix extensions are required - see http://php.net/manual/en/book.posix.php" . PHP_EOL;
102
				exit(0);
103
			}
104
			$user = posix_getpwuid(posix_getuid());
105
			$configUser = posix_getpwuid(fileowner(OC::$SERVERROOT . '/config/config.php'));
106
			if ($user['name'] !== $configUser['name']) {
107
				echo "Console has to be executed with the same user as the web server is operated" . PHP_EOL;
108
				echo "Current user: " . $user['name'] . PHP_EOL;
109
				echo "Web server user: " . $configUser['name'] . PHP_EOL;
110
				exit(0);
111
			}
112
		}
113
114
		// Create lock file first
115
		TemporaryCronClass::$lockfile = OC_Config::getValue("datadirectory", OC::$SERVERROOT . '/data') . '/cron.lock';
116
117
		// We call ownCloud from the CLI (aka cron)
118
		if ($appmode != 'cron') {
119
			// Use cron in future!
120
			OC_BackgroundJob::setExecutionType('cron');
121
		}
122
123
		// check if backgroundjobs is still running
124
		if (file_exists(TemporaryCronClass::$lockfile)) {
125
			TemporaryCronClass::$keeplock = true;
126
			TemporaryCronClass::$sent = true;
127
			echo "Another instance of cron.php is still running!";
128
			exit(1);
129
		}
130
131
		// Create a lock file
132
		touch(TemporaryCronClass::$lockfile);
133
134
		// Work
135
		$jobList = \OC::$server->getJobList();
136
		$jobs = $jobList->getAll();
137
		foreach ($jobs as $job) {
138
			$job->execute($jobList, $logger);
139
		}
140
	} else {
141
		// We call cron.php from some website
142
		if ($appmode == 'cron') {
143
			// Cron is cron :-P
144
			OC_JSON::error(array('data' => array('message' => 'Backgroundjobs are using system cron!')));
145
		} else {
146
			// Work and success :-)
147
			$jobList = \OC::$server->getJobList();
148
			$job = $jobList->getNext();
149
			if ($job != null) {
150
				$job->execute($jobList, $logger);
151
				$jobList->setLastJob($job);
152
			}
153
			OC_JSON::success();
154
		}
155
	}
156
157
	// done!
158
	TemporaryCronClass::$sent = true;
159
	// Log the successfull cron exec
160
	if (OC_Config::getValue('cron_log', true)) {
161
		OC_Appconfig::setValue('core', 'lastcron', time());
162
	}
163
	exit();
164
165
} catch (Exception $ex) {
166
	\OCP\Util::writeLog('cron', $ex->getMessage(), \OCP\Util::FATAL);
167
}
168