#!@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; } // }}} ?>