6
6
7
7
use PhpIso \Descriptor ;
8
8
use PhpIso \Descriptor \Boot ;
9
+ use PhpIso \Descriptor \PrimaryVolume ;
10
+ use PhpIso \Descriptor \SupplementaryVolume ;
11
+ use PhpIso \Descriptor \Type ;
9
12
use PhpIso \Descriptor \Volume ;
10
13
use PhpIso \Exception ;
11
14
use PhpIso \FileDirectory ;
@@ -39,11 +42,23 @@ public function run(): void
39
42
exit (2 );
40
43
}
41
44
45
+ $ extractPath = '' ;
46
+ if (isset ($ options ['extract ' ]) && is_string ($ options ['extract ' ])) {
47
+ $ extractPath = $ options ['extract ' ];
48
+ } elseif (isset ($ options ['x ' ]) && is_string ($ options ['x ' ])) {
49
+ $ extractPath = $ options ['x ' ];
50
+ }
51
+
42
52
echo 'Input ISO file: ' . $ file . PHP_EOL ;
43
53
44
54
try {
45
55
$ this ->checkIsoFile ($ file );
46
- $ this ->infoAction ($ file );
56
+
57
+ if ($ extractPath !== '' ) {
58
+ $ this ->extractAction ($ file , $ extractPath );
59
+ } else {
60
+ $ this ->infoAction ($ file );
61
+ }
47
62
} catch (Throwable $ ex ) {
48
63
$ this ->displayError ($ ex ->getMessage ());
49
64
exit (3 );
@@ -84,6 +99,74 @@ protected function infoAction(string $file): void
84
99
}
85
100
}
86
101
102
+ protected function extractAction (string $ file , string $ extractPath ): void
103
+ {
104
+ if (! is_dir ($ extractPath )) {
105
+ $ mkdirResult = mkdir ($ extractPath , 0777 , true );
106
+
107
+ if ($ mkdirResult === false ) {
108
+ throw new Exception ('Failed to create extract output directory: ' . $ extractPath );
109
+ }
110
+ }
111
+
112
+ $ isoFile = new IsoFile ($ file );
113
+
114
+ echo 'Extract ISO file to: ' . $ extractPath . PHP_EOL ;
115
+
116
+ if (isset ($ isoFile ->descriptors [Type::SUPPLEMENTARY_VOLUME_DESC ]) && $ isoFile ->descriptors [Type::SUPPLEMENTARY_VOLUME_DESC ] instanceof SupplementaryVolume) {
117
+ $ this ->extractFiles ($ isoFile ->descriptors [Type::SUPPLEMENTARY_VOLUME_DESC ], $ isoFile , $ extractPath );
118
+ } elseif (isset ($ isoFile ->descriptors [Type::PRIMARY_VOLUME_DESC ]) && $ isoFile ->descriptors [Type::PRIMARY_VOLUME_DESC ] instanceof PrimaryVolume) {
119
+ $ this ->extractFiles ($ isoFile ->descriptors [Type::PRIMARY_VOLUME_DESC ], $ isoFile , $ extractPath );
120
+ }
121
+
122
+ echo 'Extract finished! ' . PHP_EOL ;
123
+ }
124
+
125
+ protected function extractFiles (Volume $ primaryVolume , IsoFile $ isoFile , string $ destinationDir ): void
126
+ {
127
+ $ pathTable = $ primaryVolume ->loadTable ($ isoFile );
128
+
129
+ if ($ pathTable === null ) {
130
+ return ;
131
+ }
132
+
133
+ $ destinationDir = rtrim ($ destinationDir , DIRECTORY_SEPARATOR );
134
+
135
+ /** @var PathTableRecord $pathRecord */
136
+ foreach ($ pathTable as $ pathRecord ) {
137
+ // check extents
138
+ $ extents = $ pathRecord ->loadExtents ($ isoFile , $ primaryVolume ->blockSize );
139
+
140
+ if ($ extents !== false ) {
141
+ /** @var FileDirectory $extentRecord */
142
+ foreach ($ extents as $ extentRecord ) {
143
+ $ path = $ extentRecord ->fileId ;
144
+
145
+ if (! $ extentRecord ->isThis () && ! $ extentRecord ->isParent ()) {
146
+ $ fullPath = $ destinationDir . $ pathRecord ->getFullPath ($ pathTable ) . $ path ;
147
+ if ($ extentRecord ->isDirectory ()) {
148
+ $ fullPath .= DIRECTORY_SEPARATOR ;
149
+ }
150
+
151
+ if (! $ extentRecord ->isDirectory ()) {
152
+ $ location = $ extentRecord ->location ;
153
+ $ dataLength = $ extentRecord ->dataLength ;
154
+ echo $ fullPath . ' (location: ' . $ location . ') (length: ' . $ dataLength . ') ' . PHP_EOL ;
155
+
156
+ $ pathRecord ->extractFile ($ isoFile , $ primaryVolume ->blockSize , $ location , $ dataLength , $ fullPath );
157
+ } else {
158
+ if (! is_dir ($ fullPath )) {
159
+ if (mkdir ($ fullPath ) === false ) {
160
+ throw new Exception ('Failed to create directory: ' . $ fullPath );
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+
87
170
protected function infoVolume (Volume $ volumeDescriptor ): void
88
171
{
89
172
echo ' - System ID: ' . $ volumeDescriptor ->systemId . PHP_EOL ;
@@ -124,10 +207,21 @@ protected function displayFiles(Volume $volumeDescriptor, IsoFile $isoFile): voi
124
207
/** @var FileDirectory $extentRecord */
125
208
foreach ($ extents as $ extentRecord ) {
126
209
$ path = $ extentRecord ->fileId ;
127
- if ($ extentRecord ->isDirectory () && ! $ extentRecord ->isThis () && ! $ extentRecord ->isParent ()) {
128
- $ path .= '/ ' ;
210
+
211
+ if (! $ extentRecord ->isThis () && ! $ extentRecord ->isParent ()) {
212
+ $ fullPath = $ pathRecord ->getFullPath ($ pathTable ) . $ path ;
213
+ if ($ extentRecord ->isDirectory ()) {
214
+ $ fullPath .= DIRECTORY_SEPARATOR ;
215
+ }
216
+
217
+ if (! $ extentRecord ->isDirectory ()) {
218
+ $ location = $ extentRecord ->location ;
219
+ $ dataLength = $ extentRecord ->dataLength ;
220
+ echo $ fullPath . ' (location: ' . $ location . ') (length: ' . $ dataLength . ') ' . PHP_EOL ;
221
+ } else {
222
+ echo $ fullPath . PHP_EOL ;
223
+ }
129
224
}
130
- echo $ path . PHP_EOL ;
131
225
}
132
226
}
133
227
}
@@ -145,9 +239,10 @@ protected function infoBoot(Boot $bootDescriptor): void
145
239
*/
146
240
protected function parseCliArgs (): array
147
241
{
148
- $ shortopts = 'f: ' ;
242
+ $ shortopts = 'f:x:: ' ;
149
243
$ longopts = [
150
244
'file: ' ,
245
+ 'extract:: ' ,
151
246
];
152
247
$ options = getopt ($ shortopts , $ longopts , $ restIndex );
153
248
@@ -173,7 +268,8 @@ protected function displayHelp(): void
173
268
isotool [options] --file=<path>
174
269
175
270
Options:
176
- -f, --file Path for the ISO file (mandatory)
271
+ -f, --file Path for the ISO file (mandatory)
272
+ -x, --extract=<extract_path> Extract files in the given location
177
273
' ;
178
274
echo $ help ;
179
275
}
0 commit comments