237 lines
5.0 KiB
PHP
Executable File
237 lines
5.0 KiB
PHP
Executable File
#!@prefix@/bin/php -Cq
|
|
<?php // -*- PHP -*-
|
|
|
|
// {{{ setup
|
|
|
|
define('S_IFDIR', 0040000); // Directory
|
|
define('S_IFCHR', 0020000); // Character device
|
|
define('S_IFBLK', 0060000); // Block device
|
|
define('S_IFREG', 0100000); // Regular file
|
|
define('S_IFIFO', 0010000); // FIFO
|
|
define('S_IFLNK', 0120000); // Symbolic link
|
|
define('S_IFSOCK', 0140000); // Socket
|
|
|
|
require_once "PEAR.php";
|
|
require_once "Archive/Tar.php";
|
|
require_once "Console/Getopt.php";
|
|
|
|
// }}}
|
|
// {{{ options
|
|
|
|
$verbose = false;
|
|
$op_create = false;
|
|
$op_list = false;
|
|
$op_extract = false;
|
|
$use_gzip = false;
|
|
$file = '';
|
|
|
|
$progname = basename(array_shift($argv));
|
|
|
|
$options = Console_Getopt::getopt($argv, "h?ctxvzf:");
|
|
if (PEAR::isError($options)) {
|
|
usage($options);
|
|
}
|
|
|
|
$opts = $options[0];
|
|
foreach ($opts as $opt) {
|
|
switch ($opt[0]) {
|
|
case 'v': {
|
|
$verbose = true;
|
|
break;
|
|
}
|
|
case 'c': {
|
|
$op_create = true;
|
|
break;
|
|
}
|
|
case 't': {
|
|
$op_list = true;
|
|
break;
|
|
}
|
|
case 'x': {
|
|
$op_extract = true;
|
|
break;
|
|
}
|
|
case 'z': {
|
|
$use_gzip = true;
|
|
break;
|
|
}
|
|
case 'f': {
|
|
$file = $opt[1];
|
|
break;
|
|
}
|
|
case 'h':
|
|
case '?': {
|
|
usage();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($op_create + $op_list + $op_extract > 1) {
|
|
usage("Only one of -c, -t and -x can be specified at once!");
|
|
}
|
|
|
|
if ($op_create + $op_list + $op_extract == 0) {
|
|
usage("Please specify either -c, -t or -x!");
|
|
}
|
|
|
|
if (empty($file)) {
|
|
if ($op_create) {
|
|
$file = "php://stdout";
|
|
} else {
|
|
$file = "php://stdin";
|
|
}
|
|
}
|
|
|
|
// }}}
|
|
|
|
$tar = new Archive_Tar($file, $use_gzip);
|
|
$tar->setErrorHandling(PEAR_ERROR_DIE, "$progname error: %s\n");
|
|
|
|
if ($op_create) {
|
|
do_create($tar, $options[1]);
|
|
$tar->create($options[1]);
|
|
} elseif ($op_list) {
|
|
do_list($tar, $verbose);
|
|
} elseif ($op_extract) {
|
|
do_extract($tar);
|
|
}
|
|
|
|
// {{{ getrwx()
|
|
|
|
function getrwx($bits) {
|
|
$str = '';
|
|
$str .= ($bits & 4) ? 'r' : '-';
|
|
$str .= ($bits & 2) ? 'w' : '-';
|
|
$str .= ($bits & 1) ? 'x' : '-';
|
|
return $str;
|
|
}
|
|
|
|
// }}}
|
|
// {{{ getfiletype()
|
|
|
|
function getfiletype($bits) {
|
|
static $map = array(
|
|
'-' => S_IFREG,
|
|
'd' => S_IFDIR,
|
|
'l' => S_IFLNK,
|
|
'c' => S_IFCHR,
|
|
'b' => S_IFBLK,
|
|
'p' => S_IFIFO,
|
|
's' => S_IFSOCK,
|
|
);
|
|
foreach ($map as $char => $mask) {
|
|
if ($bits & $mask) {
|
|
return $char;
|
|
}
|
|
}
|
|
}
|
|
|
|
// }}}
|
|
// {{{ getuser()
|
|
|
|
function getuser($uid) {
|
|
static $cache = array();
|
|
if (isset($cache[$uid])) {
|
|
return $cache[$uid];
|
|
}
|
|
if (function_exists("posix_getpwuid")) {
|
|
if (is_array($user = @posix_getpwuid($uid))) {
|
|
$cache[$uid] = $user['name'];
|
|
return $user['name'];
|
|
}
|
|
}
|
|
$cache[$uid] = $uid;
|
|
return $uid;
|
|
}
|
|
|
|
// }}}
|
|
// {{{ getgroup()
|
|
|
|
function getgroup($gid) {
|
|
static $cache = array();
|
|
if (isset($cache[$gid])) {
|
|
return $cache[$gid];
|
|
}
|
|
if (function_exists("posix_getgrgid")) {
|
|
if (is_array($group = @posix_getgrgid($gid))) {
|
|
$cache[$gid] = $group['name'];
|
|
return $group['name'];
|
|
}
|
|
}
|
|
$cache[$gid] = $gid;
|
|
return $gid;
|
|
}
|
|
|
|
// }}}
|
|
// {{{ do_create()
|
|
|
|
function do_create(&$tar, &$files)
|
|
{
|
|
$tar->create($files);
|
|
}
|
|
|
|
// }}}
|
|
// {{{ do_list()
|
|
|
|
function do_list(&$tar, $verbose)
|
|
{
|
|
static $rwx = array(4 => 'r', 2 => 'w', 1 => 'x');
|
|
$files = $tar->listContent();
|
|
if (is_array($files) && sizeof($files) > 0) {
|
|
foreach ($files as $file) {
|
|
if ($verbose) {
|
|
$fm = (int)$file['mode'];
|
|
$mode = sprintf('%s%s%s%s', getfiletype($fm),
|
|
getrwx(($fm >> 6) & 7), getrwx(($fm >> 3) & 7),
|
|
getrwx($fm & 7));
|
|
$owner = getuser($file['uid']) . '/' . getgroup($file['gid']);
|
|
printf("%10s %-11s %7d %s %s\n", $mode, $owner, $file['size'],
|
|
date('Y-m-d H:i:s', $file['mtime']), $file['filename']);
|
|
} else {
|
|
printf("%s\n", $file['filename']);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// }}}
|
|
// {{{ do_extract()
|
|
|
|
function do_extract(&$tar, $destdir = ".")
|
|
{
|
|
$tar->extract($destdir);
|
|
}
|
|
|
|
// }}}
|
|
// {{{ usage()
|
|
|
|
function usage($errormsg = '')
|
|
{
|
|
global $progname;
|
|
$fp = fopen("php://stderr", "w");
|
|
if ($errormsg) {
|
|
if (PEAR::isError($errormsg)) {
|
|
fwrite($fp, $errormsg->getMessage() . "\n");
|
|
} else {
|
|
fwrite($fp, "$errormsg\n");
|
|
}
|
|
}
|
|
fwrite($fp, "$progname [-h|-?] {-c|-t|-x} [-z] [-v] [-f file] [file(s)...]
|
|
Options:
|
|
-h, -? Show this screen
|
|
-c Create archive
|
|
-t List archive
|
|
-x Extract archive
|
|
-z Run input/output through gzip
|
|
-f file Use <file> as input or output (default is stdin/stdout)
|
|
|
|
");
|
|
fclose($fp);
|
|
exit;
|
|
}
|
|
|
|
// }}}
|
|
|
|
?>
|