int2mode()   F
last analyzed

Complexity

Conditions 23
Paths > 20000

Size

Total Lines 54
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 29
nc 262144
nop 1
dl 0
loc 54
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
#!/usr/bin/env php
2
<?php
3
/**
4
 * EGroupware Filemanager - Command line interface
5
 *
6
 * @link http://www.egroupware.org
7
 * @package filemanager
8
 * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
9
 * @copyright (c) 2007-17 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
10
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
11
 * @version $Id$
12
 *
13
 * @todo --domain does NOT work with --user root_* for domains other then the first in header.inc.php
14
 */
15
16
use EGroupware\Api;
17
use EGroupware\Api\Vfs;
18
19
chdir(dirname(__FILE__));	// to enable our relative pathes to work
20
21
error_reporting(error_reporting() & ~E_NOTICE & ~E_DEPRECATED);
22
23
if (php_sapi_name() !== 'cli')	// security precaution: forbit calling filemanager/cli.php as web-page
24
{
25
	die('<h1>'.basename(__FILE__).' must NOT be called as web-page --> exiting !!!</h1>');
26
}
27
28
/**
29
 * callback if the session-check fails, creates session from user/passwd in $GLOBALS['egw_login_data']
30
 *
31
 * @param array &$account account_info with keys 'login', 'passwd' and optional 'passwd_type'
32
 * @return boolean/string true if we allow the access and account is set, a sessionid or false otherwise
0 ignored issues
show
Documentation Bug introduced by
The doc comment boolean/string at position 0 could not be parsed: Unknown type name 'boolean/string' at position 0 in boolean/string.
Loading history...
33
 */
34
function user_pass_from_argv(&$account)
35
{
36
	$account = $GLOBALS['egw_login_data'];
37
	//print_r($account);
38
	if (!($sessionid = $GLOBALS['egw']->session->create($account)))
39
	{
40
		usage("Wrong username or -password!");
41
	}
42
	return $sessionid;
43
}
44
45
/**
46
 * Give a usage message and exit
47
 *
48
 * @param string $error_msg ='' error-message to be printed in front of usage
49
 */
50
function usage($error_msg='')
51
{
52
	if ($error_msg)
53
	{
54
		echo "$error_msg\n\n";
55
	}
56
	$cmd = basename(__FILE__);
57
	echo "Usage:\t$cmd ls [-r|--recursive|-l|--long|-i|--inode] URL [URL2 ...]\n";
58
	echo "\t$cmd cat URL [URL2 ...]\n";
59
	echo "\t$cmd cp [-r|--recursive] [-p|--perms] URL-from URL-to\n";
60
	echo "\t$cmd cp [-r|--recursive] [-p|--perms] URL-from [URL-from2 ...] URL-to-directory\n";
61
	echo "\t$cmd rm [-r|--recursive] URL [URL2 ...]\n";
62
	echo "\t$cmd mkdir [-p|--parents] URL [URL2 ...]\n";
63
	echo "\t$cmd rmdir URL [URL2 ...]\n";
64
	echo "\t$cmd touch [-r|--recursive] [-d|--date time] URL [URL2 ...]\n";
65
	echo "\t$cmd chmod [-r|--recursive] [ugoa]*[+-=][rwx]+,... URL [URL2 ...]\n";
66
	echo "\t$cmd chown [-r|--recursive] user URL [URL2 ...]\n";
67
	echo "\t$cmd chgrp [-r|--recursive] group URL [URL2 ...]\n";
68
	echo "\t$cmd find URL [URL2 ...] [-type (d|f)][-depth][-mindepth n][-maxdepth n][-mime type[/sub]][-name pattern][-path pattern][-uid id][-user name][-nouser][-gid id][-group name][-nogroup][-size N][-cmin N][-ctime N][-mmin N][-mtime N] (N: +n --> >n, -n --> <n, n --> =n) [-limit N[,n]][-order (name|size|...)][-sort (ASC|DESC)][-hidden][-show-deleted][-(name|name-preg|path|path-preg) S]\n";
69
	echo "\t$cmd mount URL [path] (without path prints out the mounts)\n";
70
	echo "\t$cmd umount [-a|--all (restores default mounts)] URL|path\n";
71
	echo "\t$cmd eacl URL [rwx-] [user or group]\n";
72
	echo "\t$cmd lntree [sqlfs://domain]from to\n";
73
	echo "\tsudo -u apache $cmd migrate-db2fs --user root_admin --passwd password [--domain default] (migrates sqlfs content from DB to filesystem)\n";
74
75
	echo "\nCommon options: --user user --password password [--domain domain] can be used to pass eGW credentials without using the URL writing.\n";
76
	echo "\nURL: {vfs|sqlfs|filesystem}://user:password@domain/home/user/file[?option=value&...], /dir/file, ...\n";
77
78
	echo "\nUse root_{header-admin|config-user} as user and according password for root access (no user specific access control and chown).\n\n";
79
80
	exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
81
}
82
$long = $numeric = $recursive = $perms = $all = $inode = false;
83
$args = $_SERVER['argv'];
84
$cmd = basename(array_shift($args),'.php');
85
if ($args[0][0] != '-' && $args[0][0] != '/' && strpos($args[0],'://') === false)
86
{
87
	$cmd = array_shift($args);
88
}
89
90
if (!$args) $args = array('-h');
91
92
$argv = $find_options = array();
93
while(!is_null($option = array_shift($args)))
94
{
95
	if ($option == '-' || $option[0] != '-')	// no option --> argument
96
	{
97
		// remove quotes from arguments
98
		if (in_array($option[0], array('"', "'")) && $option[0] == substr($option, -1))
99
		{
100
			$option = substr($option, 1, -1);
101
		}
102
		$argv[] = $option;
103
		continue;
104
	}
105
106
	switch($option)
107
	{
108
		default:
109
			if ($cmd == 'find')
110
			{
111
				if (!in_array($option,array('-type','-depth','-mindepth','-maxdepth','-name','-path',
112
					'-uid','-user','-nouser','-gid','-group','-nogroup','-mime',
113
					'-empty','-size','-cmin','-ctime','-mmin','-mtime','-limit','-order','-sort',
114
					'-hidden','-show-deleted','-name-preg','-path','-path-preg')))
115
				{
116
					usage("Unknown find option '$option'!");
117
				}
118
				if (in_array($option,array('-empty','-depth','-nouser','-nogroup','-hidden','-show-deleted')))
119
				{
120
					$find_options[substr($option,1)] = true;
121
				}
122
				else
123
				{
124
					$find_options[str_replace('-','_',substr($option,1))] = array_shift($args);
125
				}
126
				break;
127
			}
128
			// multiple options, eg. -rp --> -r -p
129
			elseif($option[0] == '-' && $option[1] != '-' && strlen($option) > 2)
130
			{
131
				for($i = 1; $i < strlen($option); ++$i)
132
				{
133
					array_unshift($args,'-'.$option[$i]);
134
				}
135
				break;
136
			}
137
		case '-h': case '--help':
138
			usage();
139
140
		case '-l': case '--long':
141
			$long = true;
142
			break;
143
144
		case '-n': case '--numeric':
145
			$numeric = true;
146
			break;
147
148
		case '-r': case '--recursive':
149
			$recursive = true;
150
			break;
151
152
		case '-i': case '--inode':
153
			$inode = true;
154
			break;
155
156
		case '-p': case '--parents': case '--perms':
157
			if ($cmd == 'cp')
158
			{
159
				$perms = true;
160
			}
161
			else
162
			{
163
				$recursive = true;
164
			}
165
			break;
166
167
		case '-d': case '--date':
168
			$time = strtotime(array_shift($args));
169
			break;
170
171
		case '-a': case '--all':
172
			$all = true;
173
			break;
174
175
		case '--user':
176
			$user = array_shift($args);
177
			break;
178
		case '--password':
179
		case '--passwd':
180
			$passwd = array_shift($args);
181
			break;
182
		case '--domain':
183
			$domain = array_shift($args);
184
			break;
185
	}
186
}
187
if ($user && $passwd)
188
{
189
	load_egw($user,$passwd,$domain ? $domain : 'default');
190
}
191
$argc = count($argv);
192
193
switch($cmd)
194
{
195
	case 'umount':
196
		if ($argc != 1 && !$all)
197
		{
198
			usage('Wrong number of parameters!');
199
		}
200
		if (($url = $argv[0])) load_wrapper($url);
201
		if(!Vfs::$is_root)
202
		{
203
			die("You need to be root to do that!\n");
204
		}
205
		if ($all)
206
		{
207
			Api\Config::save_value('vfs_fstab',$GLOBALS['egw_info']['server']['vfs_fstab']='','phpgwapi');
208
			echo "Restored default mounts:\n";
209
		}
210
		elseif (!Vfs::umount($url))
211
		{
212
			die("$url is NOT mounted!\n");
213
		}
214
		else
215
		{
216
			echo "Successful unmounted $url:\n";
217
		}
218
		// fall trough to output current mount table
219
	case 'mount':
220
		if ($argc > 2)
221
		{
222
			usage('Wrong number of parameters!');
223
		}
224
		load_wrapper($url=$argv[0]);
225
226
		if($argc > 1 && !Vfs::$is_root)
227
		{
228
			die("You need to be root to do that!\n");
229
		}
230
		$fstab = Vfs::mount($url,$path=$argv[1]);
231
		if (is_array($fstab))
232
		{
233
			foreach($fstab as $path => $url)
234
			{
235
				echo "$url\t$path\n";
236
			}
237
		}
238
		elseif ($fstab === false)
239
		{
240
			echo "URL '$url' not found or permission denied (are you root?)!\n";
241
		}
242
		else
243
		{
244
			echo "$url successful mounted to $path\n";
245
		}
246
		break;
247
248
	case 'eacl':
249
		do_eacl($argv);
250
		break;
251
252
	case 'find':
253
		do_find($argv,$find_options);
254
		break;
255
256
	case 'lntree':
257
		do_lntree($argv[0], $argv[1]);
258
		break;
259
260
	case 'cp':
261
		do_cp($argv,$recursive,$perms);
262
		break;
263
264
	case 'rename':
265
		if (count($argv) != 2) usage('Wrong number of parameters!');
266
		load_wrapper($argv[0]);
267
		load_wrapper($argv[1]);
268
		rename($argv[0],$argv[1]);
269
		break;
270
271
	case 'migrate-db2fs':
272
		if (empty($user) || empty($passwd) || !Vfs::$is_root)
273
		{
274
			die("\nYou need to be root to do that!\n\n");
275
		}
276
		if (!is_writable($GLOBALS['egw_info']['server']['files_dir'])) exit;	// we need write access, error msg already given
277
		$fstab = Vfs::mount();
278
		if (!is_array($fstab) || !isset($fstab['/']) || strpos($fstab['/'],'storage=db') === false)
0 ignored issues
show
introduced by
The condition is_array($fstab) is always true.
Loading history...
279
		{
280
			foreach($fstab as $path => $url)
281
			{
282
				echo "$url\t$path\n";
283
			}
284
			die("\n/ NOT mounted with 'storage=db' --> no need to convert!\n\n");
285
		}
286
		$num_files = Vfs\Sqlfs\Utils::migrate_db2fs();	// throws exception on error
287
		echo "\n$num_files files migrated from DB to filesystem.\n";
288
		$new_url = preg_replace('/storage=db&?/','',$fstab['/']);
289
		if (substr($new_url,-1) == '?') $new_url = substr($new_url,0,-1);
290
		if (Vfs::mount($new_url,'/'))
291
		{
292
			echo "/ successful re-mounted on $new_url\n";
293
		}
294
		else
295
		{
296
			echo "\nre-mounting $new_url on / failed!\n\n";
297
		}
298
		break;
299
300
	default:
301
		while($argv)
302
		{
303
			$url = array_shift($argv);
304
305
			if (strpos($url, '://')) load_wrapper($url);
306
			echo "$cmd $url (long=".(int)$long.", numeric=".(int)$numeric.", recursive=".(int)$recursive.") ".implode(' ', $argv)."\n";
307
308
			switch($cmd)
309
			{
310
				case 'rm':
311
					if ($recursive)
312
					{
313
						if (!class_exists('EGroupware\\Api\\Vfs'))
314
						{
315
							die("rm -r only implemented for eGW streams!");	// dont want to repeat the code here
316
						}
317
						array_unshift($argv,$url);
318
						Vfs::remove($argv,true);
319
						$argv = array();
320
					}
321
					else
322
					{
323
						unlink($url);
324
					}
325
					break;
326
327
				case 'rmdir':
328
					rmdir($url);
329
					break;
330
331
				case 'mkdir':
332
					if (!mkdir($url,null,$recursive)) echo "Can't create directory, permission denied!\n";
333
					break;
334
335
				case 'touch':
336
				case 'chmod':
337
				case 'chown':
338
				case 'chgrp':
339
					switch($cmd)
340
					{
341
						case 'touch':
342
							$params = array($url,$time);
343
							break;
344
						case 'chmod':
345
							if (!isset($mode))
346
							{
347
								$mode = $url;	// first param is mode
348
								$url = array_shift($argv);
349
								load_wrapper($url);	// not loaded because mode was in url
350
							}
351
352
							if (strpos($mode,'+') !== false || strpos($mode,'-') !== false)
353
							{
354
								$stat = stat($url);
355
								$set = $stat['mode'];
356
							}
357
							else
358
							{
359
								$set = 0;
360
							}
361
							if (!class_exists('EGroupware\\Api\\Vfs'))
362
							{
363
								die("chmod only implemented for eGW streams!");	// dont want to repeat the code here
364
							}
365
							$set = Vfs::mode2int($mode,$set);
366
							$params = array($url,$set);
367
							break;
368
						case 'chown':
369
						case 'chgrp':
370
							$type = $cmd == 'chgrp' ? 'group' : 'user';
371
							if (!isset($owner))
372
							{
373
								$owner = $url;	// first param is owner/group
374
								$url = array_shift($argv);
375
								load_wrapper($url);	// not loaded because owner/group was in url
376
								if ($owner == 'root')
377
								{
378
									$owner = 0;
379
								}
380
								elseif (!is_numeric($owner))
381
								{
382
									if (!is_object($GLOBALS['egw']))
383
									{
384
										die("only numeric user/group-id's allowed for non eGW streams!");
385
									}
386
									if (!($owner = $GLOBALS['egw']->accounts->name2id($owner_was=$owner,'account_lid',$type[0])) ||
387
										($owner < 0) != ($cmd == 'chgrp'))
388
									{
389
										die("Unknown $type '$owner_was'!");
390
									}
391
								}
392
								elseif($owner && is_object($GLOBALS['egw']) && (!$GLOBALS['egw']->accounts->id2name($owner) ||
393
										($owner < 0) != ($cmd == 'chgrp')))
394
								{
395
									die("Unknown $type '$owner_was'!");
396
								}
397
							}
398
							$params = array($url,$owner);
399
							break;
400
					}
401
					if (($scheme = Vfs::parse_url($url,PHP_URL_SCHEME)))
402
					{
403
						load_wrapper($url);
404
					}
405
					if ($recursive && class_exists('EGroupware\\Api\\Vfs'))
406
					{
407
						array_unshift($argv,$url);
408
						$params = array($argv,null,$cmd,$params[1]);
409
						$cmd = array('EGroupware\\Api\\Vfs','find');
410
						$argv = array();	// we processed all url's
411
					}
412
					//echo "calling cmd=".print_r($cmd,true).", params=".print_r($params,true)."\n";
413
					call_user_func_array($cmd,$params);
414
					break;
415
416
				case 'cat':
417
				case 'ls':
418
				default:
419
					// recursive ls atm only for vfs://
420
					if ($cmd != 'cat' && $recursive && class_exists('EGroupware\\Api\\Vfs'))
421
					{
422
						load_wrapper($url);
423
						array_unshift($argv,$url);
424
						Vfs::find($argv,array('url'=>true,),'do_stat',array($long,$numeric,true,$inode));
425
						$argv = array();
426
					}
427
					elseif (is_dir($url) && ($dir = opendir($url)))
428
					{
429
						if ($argc)
430
						{
431
							if (!($name = basename(Vfs::parse_url($url,PHP_URL_PATH)))) $name = '/';
432
							echo "\n$name:\n";
433
						}
434
						// separate evtl. query part, to re-add it after the file-name
435
						unset($query);
436
						list($url,$query) = explode('?',$url,2);
437
						if ($query) $query = '?'.$query;
438
439
						if (substr($url,-1) == '/')
440
						{
441
							$url = substr($url,0,-1);
442
						}
443
						while(($file = readdir($dir)) !== false)
444
						{
445
							do_stat($url.'/'.$file.$query,$long,$numeric,false,$inode);
446
						}
447
						closedir($dir);
448
					}
449
					elseif ($cmd == 'cat')
450
					{
451
						if (!($f = fopen($url,'r')))
452
						{
453
							echo "File $url not found !!!\n\n";
454
						}
455
						else
456
						{
457
							if ($argc)
458
							{
459
								echo "\n".basename(Vfs::parse_url($url,PHP_URL_PATH)).":\n";
460
							}
461
							fpassthru($f);
462
							fclose($f);
463
						}
464
					}
465
					else
466
					{
467
						do_stat($url,$long,$numeric,false,$inode);
468
					}
469
					if (!$long && $cmd == 'ls') echo "\n";
470
					break;
471
			}
472
		}
473
}
474
475
/**
476
 * Load the necessary wrapper for an url or die if it cant be loaded
477
 *
478
 * @param string $url
479
 */
480
function load_wrapper($url)
481
{
482
	if (($scheme = parse_url($url,PHP_URL_SCHEME)) &&
483
		!in_array($scheme, stream_get_wrappers()))
484
	{
485
		switch($scheme)
486
		{
487
			case 'webdav':
488
			case 'webdavs':
489
				require_once('HTTP/WebDAV/Client.php');
490
				break;
491
492
			default:
493
				if (!isset($GLOBALS['egw']) && !in_array($scheme,array('smb','imap')) &&
494
					($user = parse_url($url,PHP_URL_USER)) && ($pass = parse_url($url,PHP_URL_PASS)))
495
				{
496
					load_egw($user, $pass, ($host = parse_url($url,PHP_URL_HOST)) ? $host : 'default');
497
				}
498
				// get eGW's __autoload() function
499
				include_once(EGW_SERVER_ROOT.'/api/src/loader/common.php');
500
501
				if (!Vfs::load_wrapper($scheme))
502
				{
503
					die("Unknown scheme '$scheme' in $url !!!\n\n");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
504
				}
505
				break;
506
		}
507
	}
508
}
509
510
/**
511
 * Start the eGW session, exits on wrong credintials
512
 *
513
 * @param string $user
514
 * @param string $passwd
515
 * @param string $domain
516
 */
517
function load_egw($user,$passwd,$domain='default')
518
{
519
	//echo "load_egw($user,$passwd,$domain)\n";
520
	$_REQUEST['domain'] = $domain;
521
	$GLOBALS['egw_login_data'] = array(
522
		'login'  => $user,
523
		'passwd' => $passwd,
524
		'passwd_type' => 'text',
525
	);
526
527
	if (ini_get('session.save_handler') == 'files' && !is_writable(ini_get('session.save_path')) && is_dir('/tmp') && is_writable('/tmp'))
528
	{
529
		ini_set('session.save_path','/tmp');	// regular users may have no rights to apache's session dir
530
	}
531
532
	$GLOBALS['egw_info'] = array(
533
		'flags' => array(
534
			'currentapp' => 'filemanager',
535
			'noheader' => true,
536
			'autocreate_session_callback' => 'user_pass_from_argv',
537
			'no_exception_handler' => 'cli',
538
		)
539
	);
540
541
	if (substr($user,0,5) != 'root_')
542
	{
543
		include('../header.inc.php');
544
	}
545
	else
546
	{
547
		$GLOBALS['egw_info']['flags']['currentapp'] = 'login';
548
		include('../header.inc.php');
549
550
		if (setup::check_auth($user, $passwd,
551
				'root_'.$GLOBALS['egw_info']['server']['header_admin_user'],
552
				$GLOBALS['egw_info']['server']['header_admin_password']) ||
553
			setup::check_auth($user, $passwd,
554
				'root_'.$GLOBALS['egw_domain'][$domain]['config_user'],
555
				$GLOBALS['egw_domain'][$domain]['config_passwd']))
556
		{
557
			echo "\nRoot access granted!\n";
558
			Vfs::$is_root = true;
559
		}
560
		else
561
		{
562
			die("Unknown user or password!\n");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
563
		}
564
	}
565
566
	$cmd = $GLOBALS['cmd'];
567
	if (!in_array($cmd,array('ls','find','mount','umount','eacl','touch','chmod','chown','chgrp')) && $GLOBALS['egw_info']['server']['files_dir'] && !is_writable($GLOBALS['egw_info']['server']['files_dir']))
568
	{
569
		echo "\nError: eGroupWare's files directory {$GLOBALS['egw_info']['server']['files_dir']} is NOT writable by the user running ".basename(__FILE__)."!\n".
570
			"--> Please run it as the same user the webserver uses or root, otherwise the $cmd command will fail!\n\n";
571
	}
572
}
573
574
/**
575
 * Set, delete or show the extended acl for a given path
576
 *
577
 * @param array $argv
578
 */
579
function do_eacl(array $argv)
580
{
581
	$argc = count($argv);
582
583
	if ($argc < 1 || $argc > 3)
584
	{
585
		usage('Wrong number of parameters!');
586
	}
587
	load_wrapper($url = $argv[0]);
588
	if (!class_exists('EGroupware\\Api\\Vfs'))
589
	{
590
		die('eacl only implemented for eGW streams!');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
591
	}
592
	if (!file_exists($url))
593
	{
594
		die("$url: no such file our directory!\n");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
595
	}
596
	if ($argc == 1)
597
	{
598
		foreach(Vfs::get_eacl($url) as $acl)
599
		{
600
			$mode = ($acl['rights'] & Vfs::READABLE ? 'r' : '-').
601
				($acl['rights'] & Vfs::WRITABLE ? 'w' : '-').
602
				($acl['rights'] & Vfs::EXECUTABLE ? 'x' : '-');
603
			echo $acl['path']."\t$mode\t".$GLOBALS['egw']->accounts->id2name($acl['owner'])."\n";
604
		}
605
		return;
606
	}
607
	if ($argc > 1 && !is_numeric($argv[1]))
608
	{
609
		$mode=$argv[1];
610
		$argv[1] = null;
611
		for($i = 0; $mode[$i]; ++$i)
612
		{
613
			switch($mode[$i])
614
			{
615
				case 'x': $argv[1] |= Vfs::EXECUTABLE; break;
616
				case 'w': $argv[1] |= Vfs::WRITABLE; break;
617
				case 'r': $argv[1] |= Vfs::READABLE; break;
618
			}
619
		}
620
	}
621
	if (!Vfs::eacl($url,$argv[1],$argc > 2 && !is_numeric($argv[2]) ? $GLOBALS['egw']->accounts->name2id($argv[2]) : $argv[2]))
622
	{
623
		echo "Error setting extended Acl for $argv[0]!\n";
624
	}
625
}
626
627
/**
628
 * Give the stats for one file
629
 *
630
 * @param string $url
631
 * @param boolean $long =false true=long listing with owner,group,size,perms, default false only filename
632
 * @param boolean $numeric =false true=give numeric uid&gid, else resolve the id to a name
633
 * @param boolean $full_path =false true=give full path instead of just filename
634
 * @param boolean $inode =false true=display inode (sqlfs id)
635
 */
636
function do_stat($url,$long=false,$numeric=false,$full_path=false,$inode=false)
637
{
638
	//echo "do_stat($url,$long,$numeric,$full_path)\n";
639
	$bname = Vfs::parse_url($url,PHP_URL_PATH);
640
641
	if (!$full_path)
642
	{
643
		$bname = basename($bname);
644
	}
645
	if (!($stat = @lstat($url)))
646
	{
647
		echo "$bname: no such file or directory!\n";
648
	}
649
	elseif ($long)
650
	{
651
		//echo $url; print_r($stat);
652
653
		if (class_exists('EGroupware\\Api\\Vfs'))
654
		{
655
			$perms = Vfs::int2mode($stat['mode']);
656
		}
657
		else
658
		{
659
			$perms = int2mode($stat['mode']);
660
		}
661
		if ($numeric)
662
		{
663
			$uid = $stat['uid'];
664
			$gid = $stat['gid'];
665
		}
666
		else
667
		{
668
			if ($stat['uid'])
669
			{
670
				$uid = isset($GLOBALS['egw']) ? $GLOBALS['egw']->accounts->id2name($stat['uid']) :
671
					(function_exists('posix_getpwuid') ? posix_getpwuid($stat['uid']) : $stat['uid']);
672
				if (is_array($uid)) $uid = $uid['name'];
673
				if (empty($uid)) $uid = $stat['uid'];
674
			}
675
			if (!isset($uid)) $uid = 'root';
676
			if ($stat['gid'])
677
			{
678
				$gid = isset($GLOBALS['egw']) ? $GLOBALS['egw']->accounts->id2name(-abs($stat['gid'])) :
679
					(function_exists('posix_getgrgid') ? posix_getgrgid($stat['gid']) : $stat['gid']);
680
				if (is_array($gid)) $gid = $gid['name'];
681
				if (empty($gid)) $gid = $stat['gid'];
682
			}
683
			if (!isset($gid)) $gid = 'root';
684
		}
685
		$size = hsize($stat['size']);
686
		$mtime = date('Y-m-d H:i:s',$stat['mtime']);
687
		$nlink = $stat['nlink'];
688
		if (($stat['mode'] & 0xA000) == 0xA000)
689
		{
690
			$symlink = " -> ".(class_exists('EGroupware\\Api\\Vfs') ? Vfs::readlink($url) : readlink($url));
691
		}
692
		if ($inode)
693
		{
694
			echo $stat['ino']."\t";
695
		}
696
		echo "$perms $nlink\t$uid\t$gid\t$size\t$mtime\t$bname$symlink\n";
697
	}
698
	else
699
	{
700
		echo "$bname\t";
701
	}
702
}
703
704
function hsize($size)
705
{
706
	if ($size < 1024) return $size;
707
	if ($size < 1024*1024) return sprintf('%3.1lfk',(float)$size/1024);
708
	return sprintf('%3.1lfM',(float)$size/(1024*1024));
709
}
710
711
712
function do_cp($argv,$recursive=false,$perms=false)
713
{
714
	$to = array_pop($argv);
715
	load_wrapper($to);
716
717
	$to_exists = file_exists($to);
718
719
	if (count($argv) > 1 && $to_exists && !is_dir($to))
720
	{
721
		usage("No such directory '$to'!");
722
	}
723
	$anz_dirs = $anz_files = 0;
724
	foreach($argv as $from)
725
	{
726
		if (is_dir($from) && (!file_exists($to) || is_dir($to)) && $recursive && class_exists('EGroupware\\Api\\Vfs'))
727
		{
728
			foreach(Vfs::find($from,array('url' => true)) as $f)
729
			{
730
				$t = $to.substr($f,strlen($from));
731
				if (is_dir($f))
732
				{
733
					++$anz_dirs;
734
					mkdir($t);
735
				}
736
				else
737
				{
738
					++$anz_files;
739
					_cp($f,$t);
740
				}
741
				if ($perms) _cp_perms($f,$t);
742
			}
743
			echo ($anz_dirs?"$anz_dirs dir(s) created and ":'')."$anz_files file(s) copied.\n";
744
		}
745
		else
746
		{
747
			_cp($from,$to,true);
748
			if ($perms) _cp_perms($from,$to);
749
		}
750
	}
751
}
752
753
function _cp($from,$to,$verbose=false)
754
{
755
	load_wrapper($from);
756
757
	if (is_dir($to))
758
	{
759
		$path = Vfs::parse_url($from,PHP_URL_PATH);
760
		if (is_dir($to))
761
		{
762
			list($to,$query) = explode('?',$to,2);
763
			$to .= '/'.basename($path).($query ? '?'.$query : '');
764
		}
765
	}
766
	if (!($from_fp = fopen($from,'r')))
767
	{
768
		die("File $from not found!\n");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
769
	}
770
	if (!($to_fp = fopen($to,'w')))
771
	{
772
		die("Can't open $to for writing!\n");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
773
	}
774
	//stream_filter_append($from_fp,'convert.base64-decode');
775
	$count = stream_copy_to_stream($from_fp,$to_fp);
776
777
	if ($verbose) echo hsize($count)." bytes written to $to\n";
778
779
	fclose($from_fp);
780
781
	if (!fclose($to_fp))
782
	{
783
		die("Error closing $to!\n");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
784
	}
785
}
786
787
788
function _cp_perms($from,$to)
789
{
790
	if (($from_stat = stat($from)) && ($to_stat = stat($to)))
791
	{
792
		foreach(array(
793
			'mode' => 'chmod',
794
			'uid'  => 'chown',
795
			'gid'  => 'chgrp',
796
		) as $perm => $cmd)
797
		{
798
			if ($from_stat[$perm] != $to_stat[$perm])
799
			{
800
				//echo "Vfs::$cmd($to,{$from_stat[$perm]}\n";
801
				call_user_func(array('EGroupware\\Api\\Vfs',$cmd),$to,$from_stat[$perm]);
802
			}
803
		}
804
	}
805
}
806
807
function do_find($bases,$options)
808
{
809
	foreach($bases as $url)
810
	{
811
		load_wrapper($url);
812
	}
813
	$options['url'] = true;	// we use url's not vfs pathes in filemanager/cli.php
814
815
	foreach(Vfs::find($bases,$options) as $path)
816
	{
817
		echo "$path\n";
818
	}
819
}
820
821
function do_lntree($from,$to)
822
{
823
	echo "lntree $from $to\n";
824
	if ($from[0] == '/') $from = 'sqlfs://default'.$from;
825
	load_wrapper($from);
826
827
	if (!file_exists($from))
828
	{
829
		usage("Directory '$from' does NOT exist!");
830
	}
831
	elseif ($to[0] != '/' || file_exists($to))
832
	{
833
		usage("Directory '$to' does not exist!");
834
	}
835
	elseif (!is_writable(dirname($to)))
836
	{
837
		usage("Directory '$to' is not writable!");
838
	}
839
	Vfs::find($from, array(
840
		'url' => true,
841
	), '_ln', array($to));
842
}
843
844
function _ln($src, $base, $stat)
845
{
846
	//echo "_ln('$src', '$base', ".array2string($stat).")\n";
847
	$dst = $base.Vfs::parse_url($src, PHP_URL_PATH);
0 ignored issues
show
Bug introduced by
Are you sure EGroupware\Api\Vfs::parse_url($src, PHP_URL_PATH) of type array|boolean|string can be used in concatenation? ( Ignorable by Annotation )

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

847
	$dst = $base./** @scrutinizer ignore-type */ Vfs::parse_url($src, PHP_URL_PATH);
Loading history...
848
849
	if (is_link($src))
850
	{
851
		if (($target = Vfs\Sqlfs\StreamWrapper::readlink($src)))
852
		{
853
			if ($target[0] != '/')
854
			{
855
				$target = Vfs::dirname($src).'/'.$target;
0 ignored issues
show
Bug introduced by
Are you sure $target of type string|true can be used in concatenation? ( Ignorable by Annotation )

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

855
				$target = Vfs::dirname($src).'/'./** @scrutinizer ignore-type */ $target;
Loading history...
Bug introduced by
Are you sure EGroupware\Api\Vfs::dirname($src) of type false|string can be used in concatenation? ( Ignorable by Annotation )

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

855
				$target = /** @scrutinizer ignore-type */ Vfs::dirname($src).'/'.$target;
Loading history...
856
			}
857
			echo "_ln('$src', '$base')\tsymlink('$base$target', '$dst')\n";
858
			symlink($base.$target, $dst);
859
		}
860
		else
861
		{
862
			echo "_ln('$src', '$base')\tsqlfs::readlink('$src') failed\n";
863
		}
864
	}
865
	elseif (is_dir($src))
866
	{
867
		echo "_ln('$src', '$base')\tmkdir('$dst', 0700, true)\n";
868
		mkdir($dst, 0700, true);
869
	}
870
	else
871
	{
872
		$target = Vfs\Sqlfs\StreamWrapper::_fs_path($stat['ino']);
873
		echo "_ln('$src', '$base')\tlink('$target', '$dst')\n";
874
		link($target, $dst);
875
	}
876
}
877
878
/**
879
 * Convert a numerical mode to a symbolic mode-string
880
 *
881
 * @param int $mode
882
 * @return string
883
 */
884
function int2mode( $mode )
885
{
886
	if(($mode & 0xA000) == 0xA000) // Symbolic Link
887
	{
888
		$sP = 'l';
889
	}
890
	elseif(($mode & 0xC000) == 0xC000) // Socket
891
	{
892
		$sP = 's';
893
	}
894
	elseif($mode & 0x1000)     // FIFO pipe
895
	{
896
		$sP = 'p';
897
	}
898
	elseif($mode & 0x2000) // Character special
899
	{
900
		$sP = 'c';
901
	}
902
	elseif($mode & 0x4000) // Directory
903
	{
904
		$sP = 'd';
905
	}
906
	elseif($mode & 0x6000) // Block special
907
	{
908
		$sP = 'b';
909
	}
910
	elseif($mode & 0x8000) // Regular
911
	{
912
		$sP = '-';
913
	}
914
	else                         // UNKNOWN
915
	{
916
		$sP = 'u';
917
	}
918
919
	// owner
920
	$sP .= (($mode & 0x0100) ? 'r' : '-') .
921
	(($mode & 0x0080) ? 'w' : '-') .
922
	(($mode & 0x0040) ? (($mode & 0x0800) ? 's' : 'x' ) :
923
	(($mode & 0x0800) ? 'S' : '-'));
924
925
	// group
926
	$sP .= (($mode & 0x0020) ? 'r' : '-') .
927
	(($mode & 0x0010) ? 'w' : '-') .
928
	(($mode & 0x0008) ? (($mode & 0x0400) ? 's' : 'x' ) :
929
	(($mode & 0x0400) ? 'S' : '-'));
930
931
	// world
932
	$sP .= (($mode & 0x0004) ? 'r' : '-') .
933
	(($mode & 0x0002) ? 'w' : '-') .
934
	(($mode & 0x0001) ? (($mode & 0x0200) ? 't' : 'x' ) :
935
	(($mode & 0x0200) ? 'T' : '-'));
936
937
	return $sP;
938
}
939