Chris@18
|
1 #!@prefix@/bin/php -Cq
|
Chris@18
|
2 <?php // -*- PHP -*-
|
Chris@18
|
3
|
Chris@18
|
4 // {{{ setup
|
Chris@18
|
5
|
Chris@18
|
6 define('S_IFDIR', 0040000); // Directory
|
Chris@18
|
7 define('S_IFCHR', 0020000); // Character device
|
Chris@18
|
8 define('S_IFBLK', 0060000); // Block device
|
Chris@18
|
9 define('S_IFREG', 0100000); // Regular file
|
Chris@18
|
10 define('S_IFIFO', 0010000); // FIFO
|
Chris@18
|
11 define('S_IFLNK', 0120000); // Symbolic link
|
Chris@18
|
12 define('S_IFSOCK', 0140000); // Socket
|
Chris@18
|
13
|
Chris@18
|
14 require_once "PEAR.php";
|
Chris@18
|
15 require_once "Archive/Tar.php";
|
Chris@18
|
16 require_once "Console/Getopt.php";
|
Chris@18
|
17
|
Chris@18
|
18 // }}}
|
Chris@18
|
19 // {{{ options
|
Chris@18
|
20
|
Chris@18
|
21 $verbose = false;
|
Chris@18
|
22 $op_create = false;
|
Chris@18
|
23 $op_list = false;
|
Chris@18
|
24 $op_extract = false;
|
Chris@18
|
25 $use_gzip = false;
|
Chris@18
|
26 $file = '';
|
Chris@18
|
27
|
Chris@18
|
28 $progname = basename(array_shift($argv));
|
Chris@18
|
29
|
Chris@18
|
30 $options = Console_Getopt::getopt($argv, "h?ctxvzf:");
|
Chris@18
|
31 if (PEAR::isError($options)) {
|
Chris@18
|
32 usage($options);
|
Chris@18
|
33 }
|
Chris@18
|
34
|
Chris@18
|
35 $opts = $options[0];
|
Chris@18
|
36 foreach ($opts as $opt) {
|
Chris@18
|
37 switch ($opt[0]) {
|
Chris@18
|
38 case 'v': {
|
Chris@18
|
39 $verbose = true;
|
Chris@18
|
40 break;
|
Chris@18
|
41 }
|
Chris@18
|
42 case 'c': {
|
Chris@18
|
43 $op_create = true;
|
Chris@18
|
44 break;
|
Chris@18
|
45 }
|
Chris@18
|
46 case 't': {
|
Chris@18
|
47 $op_list = true;
|
Chris@18
|
48 break;
|
Chris@18
|
49 }
|
Chris@18
|
50 case 'x': {
|
Chris@18
|
51 $op_extract = true;
|
Chris@18
|
52 break;
|
Chris@18
|
53 }
|
Chris@18
|
54 case 'z': {
|
Chris@18
|
55 $use_gzip = true;
|
Chris@18
|
56 break;
|
Chris@18
|
57 }
|
Chris@18
|
58 case 'f': {
|
Chris@18
|
59 $file = $opt[1];
|
Chris@18
|
60 break;
|
Chris@18
|
61 }
|
Chris@18
|
62 case 'h':
|
Chris@18
|
63 case '?': {
|
Chris@18
|
64 usage();
|
Chris@18
|
65 break;
|
Chris@18
|
66 }
|
Chris@18
|
67 }
|
Chris@18
|
68 }
|
Chris@18
|
69
|
Chris@18
|
70 if ($op_create + $op_list + $op_extract > 1) {
|
Chris@18
|
71 usage("Only one of -c, -t and -x can be specified at once!");
|
Chris@18
|
72 }
|
Chris@18
|
73
|
Chris@18
|
74 if ($op_create + $op_list + $op_extract == 0) {
|
Chris@18
|
75 usage("Please specify either -c, -t or -x!");
|
Chris@18
|
76 }
|
Chris@18
|
77
|
Chris@18
|
78 if (empty($file)) {
|
Chris@18
|
79 if ($op_create) {
|
Chris@18
|
80 $file = "php://stdout";
|
Chris@18
|
81 } else {
|
Chris@18
|
82 $file = "php://stdin";
|
Chris@18
|
83 }
|
Chris@18
|
84 }
|
Chris@18
|
85
|
Chris@18
|
86 // }}}
|
Chris@18
|
87
|
Chris@18
|
88 $tar = new Archive_Tar($file, $use_gzip);
|
Chris@18
|
89 $tar->setErrorHandling(PEAR_ERROR_DIE, "$progname error: %s\n");
|
Chris@18
|
90
|
Chris@18
|
91 if ($op_create) {
|
Chris@18
|
92 do_create($tar, $options[1]);
|
Chris@18
|
93 $tar->create($options[1]);
|
Chris@18
|
94 } elseif ($op_list) {
|
Chris@18
|
95 do_list($tar, $verbose);
|
Chris@18
|
96 } elseif ($op_extract) {
|
Chris@18
|
97 do_extract($tar);
|
Chris@18
|
98 }
|
Chris@18
|
99
|
Chris@18
|
100 // {{{ getrwx()
|
Chris@18
|
101
|
Chris@18
|
102 function getrwx($bits) {
|
Chris@18
|
103 $str = '';
|
Chris@18
|
104 $str .= ($bits & 4) ? 'r' : '-';
|
Chris@18
|
105 $str .= ($bits & 2) ? 'w' : '-';
|
Chris@18
|
106 $str .= ($bits & 1) ? 'x' : '-';
|
Chris@18
|
107 return $str;
|
Chris@18
|
108 }
|
Chris@18
|
109
|
Chris@18
|
110 // }}}
|
Chris@18
|
111 // {{{ getfiletype()
|
Chris@18
|
112
|
Chris@18
|
113 function getfiletype($bits) {
|
Chris@18
|
114 static $map = array(
|
Chris@18
|
115 '-' => S_IFREG,
|
Chris@18
|
116 'd' => S_IFDIR,
|
Chris@18
|
117 'l' => S_IFLNK,
|
Chris@18
|
118 'c' => S_IFCHR,
|
Chris@18
|
119 'b' => S_IFBLK,
|
Chris@18
|
120 'p' => S_IFIFO,
|
Chris@18
|
121 's' => S_IFSOCK,
|
Chris@18
|
122 );
|
Chris@18
|
123 foreach ($map as $char => $mask) {
|
Chris@18
|
124 if ($bits & $mask) {
|
Chris@18
|
125 return $char;
|
Chris@18
|
126 }
|
Chris@18
|
127 }
|
Chris@18
|
128 }
|
Chris@18
|
129
|
Chris@18
|
130 // }}}
|
Chris@18
|
131 // {{{ getuser()
|
Chris@18
|
132
|
Chris@18
|
133 function getuser($uid) {
|
Chris@18
|
134 static $cache = array();
|
Chris@18
|
135 if (isset($cache[$uid])) {
|
Chris@18
|
136 return $cache[$uid];
|
Chris@18
|
137 }
|
Chris@18
|
138 if (function_exists("posix_getpwuid")) {
|
Chris@18
|
139 if (is_array($user = @posix_getpwuid($uid))) {
|
Chris@18
|
140 $cache[$uid] = $user['name'];
|
Chris@18
|
141 return $user['name'];
|
Chris@18
|
142 }
|
Chris@18
|
143 }
|
Chris@18
|
144 $cache[$uid] = $uid;
|
Chris@18
|
145 return $uid;
|
Chris@18
|
146 }
|
Chris@18
|
147
|
Chris@18
|
148 // }}}
|
Chris@18
|
149 // {{{ getgroup()
|
Chris@18
|
150
|
Chris@18
|
151 function getgroup($gid) {
|
Chris@18
|
152 static $cache = array();
|
Chris@18
|
153 if (isset($cache[$gid])) {
|
Chris@18
|
154 return $cache[$gid];
|
Chris@18
|
155 }
|
Chris@18
|
156 if (function_exists("posix_getgrgid")) {
|
Chris@18
|
157 if (is_array($group = @posix_getgrgid($gid))) {
|
Chris@18
|
158 $cache[$gid] = $group['name'];
|
Chris@18
|
159 return $group['name'];
|
Chris@18
|
160 }
|
Chris@18
|
161 }
|
Chris@18
|
162 $cache[$gid] = $gid;
|
Chris@18
|
163 return $gid;
|
Chris@18
|
164 }
|
Chris@18
|
165
|
Chris@18
|
166 // }}}
|
Chris@18
|
167 // {{{ do_create()
|
Chris@18
|
168
|
Chris@18
|
169 function do_create(&$tar, &$files)
|
Chris@18
|
170 {
|
Chris@18
|
171 $tar->create($files);
|
Chris@18
|
172 }
|
Chris@18
|
173
|
Chris@18
|
174 // }}}
|
Chris@18
|
175 // {{{ do_list()
|
Chris@18
|
176
|
Chris@18
|
177 function do_list(&$tar, $verbose)
|
Chris@18
|
178 {
|
Chris@18
|
179 static $rwx = array(4 => 'r', 2 => 'w', 1 => 'x');
|
Chris@18
|
180 $files = $tar->listContent();
|
Chris@18
|
181 if (is_array($files) && sizeof($files) > 0) {
|
Chris@18
|
182 foreach ($files as $file) {
|
Chris@18
|
183 if ($verbose) {
|
Chris@18
|
184 $fm = (int)$file['mode'];
|
Chris@18
|
185 $mode = sprintf('%s%s%s%s', getfiletype($fm),
|
Chris@18
|
186 getrwx(($fm >> 6) & 7), getrwx(($fm >> 3) & 7),
|
Chris@18
|
187 getrwx($fm & 7));
|
Chris@18
|
188 $owner = getuser($file['uid']) . '/' . getgroup($file['gid']);
|
Chris@18
|
189 printf("%10s %-11s %7d %s %s\n", $mode, $owner, $file['size'],
|
Chris@18
|
190 date('Y-m-d H:i:s', $file['mtime']), $file['filename']);
|
Chris@18
|
191 } else {
|
Chris@18
|
192 printf("%s\n", $file['filename']);
|
Chris@18
|
193 }
|
Chris@18
|
194 }
|
Chris@18
|
195 }
|
Chris@18
|
196 }
|
Chris@18
|
197
|
Chris@18
|
198 // }}}
|
Chris@18
|
199 // {{{ do_extract()
|
Chris@18
|
200
|
Chris@18
|
201 function do_extract(&$tar, $destdir = ".")
|
Chris@18
|
202 {
|
Chris@18
|
203 $tar->extract($destdir);
|
Chris@18
|
204 }
|
Chris@18
|
205
|
Chris@18
|
206 // }}}
|
Chris@18
|
207 // {{{ usage()
|
Chris@18
|
208
|
Chris@18
|
209 function usage($errormsg = '')
|
Chris@18
|
210 {
|
Chris@18
|
211 global $progname;
|
Chris@18
|
212 $fp = fopen("php://stderr", "w");
|
Chris@18
|
213 if ($errormsg) {
|
Chris@18
|
214 if (PEAR::isError($errormsg)) {
|
Chris@18
|
215 fwrite($fp, $errormsg->getMessage() . "\n");
|
Chris@18
|
216 } else {
|
Chris@18
|
217 fwrite($fp, "$errormsg\n");
|
Chris@18
|
218 }
|
Chris@18
|
219 }
|
Chris@18
|
220 fwrite($fp, "$progname [-h|-?] {-c|-t|-x} [-z] [-v] [-f file] [file(s)...]
|
Chris@18
|
221 Options:
|
Chris@18
|
222 -h, -? Show this screen
|
Chris@18
|
223 -c Create archive
|
Chris@18
|
224 -t List archive
|
Chris@18
|
225 -x Extract archive
|
Chris@18
|
226 -z Run input/output through gzip
|
Chris@18
|
227 -f file Use <file> as input or output (default is stdin/stdout)
|
Chris@18
|
228
|
Chris@18
|
229 ");
|
Chris@18
|
230 fclose($fp);
|
Chris@18
|
231 exit;
|
Chris@18
|
232 }
|
Chris@18
|
233
|
Chris@18
|
234 // }}}
|
Chris@18
|
235
|
Chris@18
|
236 ?>
|