@@ -49,6 +49,9 @@ class Scan extends Command {
4949 protected $ filesCounter = 0 ;
5050 /** @var bool */
5151 protected $ interrupted = false ;
52+ /** @var bool */
53+ protected $ php_pcntl_signal = true ;
54+
5255
5356
5457 public function __construct (\OC \User \Manager $ userManager ) {
@@ -93,15 +96,22 @@ protected function configure() {
9396
9497 protected function scanFiles ($ user , $ path , $ verbose , OutputInterface $ output ) {
9598 $ scanner = new \OC \Files \Utils \Scanner ($ user , \OC ::$ server ->getDatabaseConnection (), \OC ::$ server ->getLogger ());
99+ # check on each file/folder if there was a user interrupt (ctrl-c) and throw an exeption
96100 # printout and count
97101 if ($ verbose ) {
98102 $ scanner ->listen ('\OC\Files\Utils\Scanner ' , 'scanFile ' , function ($ path ) use ($ output ) {
99- $ output ->writeln ("Scanning file <info>$ path</info> " );
103+ $ output ->writeln ("\t File <info>$ path</info> " );
100104 $ this ->filesCounter += 1 ;
105+ if ($ this ->hasBeenInterrupted ()) {
106+ throw new \Exception ('ctrl-c ' );
107+ }
101108 });
102109 $ scanner ->listen ('\OC\Files\Utils\Scanner ' , 'scanFolder ' , function ($ path ) use ($ output ) {
103- $ output ->writeln ("Scanning folder <info>$ path</info> " );
110+ $ output ->writeln ("\t Folder <info>$ path</info> " );
104111 $ this ->foldersCounter += 1 ;
112+ if ($ this ->hasBeenInterrupted ()) {
113+ throw new \Exception ('ctrl-c ' );
114+ }
105115 });
106116 $ scanner ->listen ('\OC\Files\Utils\Scanner ' , 'StorageNotAvailable ' , function (StorageNotAvailableException $ e ) use ($ output ) {
107117 $ output ->writeln ("Error while scanning, storage not available ( " . $ e ->getMessage () . ") " );
@@ -110,9 +120,15 @@ protected function scanFiles($user, $path, $verbose, OutputInterface $output) {
110120 } else {
111121 $ scanner ->listen ('\OC\Files\Utils\Scanner ' , 'scanFile ' , function ($ path ) use ($ output ) {
112122 $ this ->filesCounter += 1 ;
123+ if ($ this ->hasBeenInterrupted ()) {
124+ throw new \Exception ('ctrl-c ' );
125+ }
113126 });
114127 $ scanner ->listen ('\OC\Files\Utils\Scanner ' , 'scanFolder ' , function ($ path ) use ($ output ) {
115128 $ this ->foldersCounter += 1 ;
129+ if ($ this ->hasBeenInterrupted ()) {
130+ throw new \Exception ('ctrl-c ' );
131+ }
116132 });
117133 }
118134
@@ -121,6 +137,9 @@ protected function scanFiles($user, $path, $verbose, OutputInterface $output) {
121137 } catch (ForbiddenException $ e ) {
122138 $ output ->writeln ("<error>Home storage for user $ user not writable</error> " );
123139 $ output ->writeln ("Make sure you're running the scan command only as the user the web server runs as " );
140+ } catch (\Exception $ e ) {
141+ # exit the function if ctrl-c has been pressed
142+ return ;
124143 }
125144 }
126145
@@ -137,11 +156,6 @@ protected function execute(InputInterface $input, OutputInterface $output) {
137156 $ users = $ input ->getArgument ('user_id ' );
138157 }
139158
140- if (count ($ users ) === 0 ) {
141- $ output ->writeln ("<error>Please specify the user id to scan, \"--all \" to scan for all users or \"--path=... \"</error> " );
142- return ;
143- }
144-
145159 # no messaging level option means: no full printout but statistics
146160 # $quiet means no print at all
147161 # $verbose means full printout including statistics
@@ -159,18 +173,38 @@ protected function execute(InputInterface $input, OutputInterface $output) {
159173 $ verbose = false ;
160174 }
161175
176+ # check quantity of users to be process and show it on the command line
177+ $ users_total = count ($ users );
178+ if ($ users_total === 0 ) {
179+ $ output ->writeln ("<error>Please specify the user id to scan, \"--all \" to scan for all users or \"--path=... \"</error> " );
180+ return ;
181+ } else {
182+ if ($ users_total > 1 ) {
183+ $ output ->writeln ("\nScanning files for $ users_total users " );
184+ }
185+ }
186+
162187 $ this ->initTools ();
163188
189+ $ user_count = 0 ;
164190 foreach ($ users as $ user ) {
165191 if (is_object ($ user )) {
166192 $ user = $ user ->getUID ();
167193 }
168194 $ path = $ inputPath ? $ inputPath : '/ ' . $ user ;
195+ $ user_count += 1 ;
169196 if ($ this ->userManager ->userExists ($ user )) {
197+ # add an extra line when verbose is set to optical seperate users
198+ if ($ verbose ) {$ output ->writeln ("" ); }
199+ $ output ->writeln ("Starting scan for user $ user_count out of $ users_total ( $ user) " );
170200 # full: printout data if $verbose was set
171201 $ this ->scanFiles ($ user , $ path , $ verbose , $ output );
172202 } else {
173- $ output ->writeln ("<error>Unknown user $ user</error> " );
203+ $ output ->writeln ("<error>Unknown user $ user_count $ user</error> " );
204+ }
205+ # check on each user if there was a user interrupt (ctrl-c) and exit foreach
206+ if ($ this ->hasBeenInterrupted ()) {
207+ break ;
174208 }
175209 }
176210
@@ -182,17 +216,6 @@ protected function execute(InputInterface $input, OutputInterface $output) {
182216 }
183217
184218
185- /**
186- * Checks if the command was interrupted by ctrl-c
187- */
188- protected function checkForInterruption ($ output ) {
189- if ($ this ->hasBeenInterrupted ()) {
190- $ this ->presentResults ($ output );
191- exit ;
192- }
193- }
194-
195-
196219 /**
197220 * Initialises some useful tools for the Command
198221 */
@@ -202,14 +225,19 @@ protected function initTools() {
202225 // Convert PHP errors to exceptions
203226 set_error_handler ([$ this , 'exceptionErrorHandler ' ], E_ALL );
204227
205- // Collect interrupts and notify the running command
206- pcntl_signal (SIGTERM , [$ this , 'cancelOperation ' ]);
207- pcntl_signal (SIGINT , [$ this , 'cancelOperation ' ]);
228+ // check if the php pcntl_signal functions are accessible
229+ if (function_exists ('pcntl_signal ' )) {
230+ // Collect interrupts and notify the running command
231+ pcntl_signal (SIGTERM , [$ this , 'cancelOperation ' ]);
232+ pcntl_signal (SIGINT , [$ this , 'cancelOperation ' ]);
233+ } else {
234+ $ this ->php_pcntl_signal = false ;
235+ }
208236 }
209237
210238
211239 /**
212- * Changes the status of the command to "interrupted"
240+ * Changes the status of the command to "interrupted" if ctrl-c has been pressed
213241 *
214242 * Gives a chance to the command to properly terminate what it's doing
215243 */
@@ -218,6 +246,24 @@ private function cancelOperation() {
218246 }
219247
220248
249+ /**
250+ * @return bool
251+ */
252+ protected function hasBeenInterrupted () {
253+ // return always false if pcntl_signal functions are not accessible
254+ if ($ this ->php_pcntl_signal ) {
255+ pcntl_signal_dispatch ();
256+ if ($ this ->interrupted ) {
257+ return true ;
258+ } else {
259+ return false ;
260+ }
261+ } else {
262+ return false ;
263+ }
264+ }
265+
266+
221267 /**
222268 * Processes PHP errors as exceptions in order to be able to keep track of problems
223269 *
@@ -239,20 +285,6 @@ public function exceptionErrorHandler($severity, $message, $file, $line) {
239285 }
240286
241287
242- /**
243- * @return bool
244- */
245- protected function hasBeenInterrupted () {
246- $ cancelled = false ;
247- pcntl_signal_dispatch ();
248- if ($ this ->interrupted ) {
249- $ cancelled = true ;
250- }
251-
252- return $ cancelled ;
253- }
254-
255-
256288 /**
257289 * @param OutputInterface $output
258290 */
@@ -300,7 +332,8 @@ protected function showSummary($headers, $rows, OutputInterface $output) {
300332 */
301333 protected function formatExecTime () {
302334 list ($ secs , $ tens ) = explode ('. ' , sprintf ("%.1f " , ($ this ->execTime )));
303- $ niceDate = date ('H:i:s ' , $ secs ) . '. ' . $ tens ;
335+ # add the following to $niceDate if you want to have microsecons added: . '.' . $tens;
336+ $ niceDate = date ('H:i:s ' , $ secs );
304337
305338 return $ niceDate ;
306339 }
0 commit comments