Skip to content

Commit 6a160c9

Browse files
author
cradu
committed
Added cli tool
1 parent d5c5bd9 commit 6a160c9

File tree

7 files changed

+279
-9
lines changed

7 files changed

+279
-9
lines changed

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,75 @@ Installation
3636
This class can easily be installed via [Composer](https://getcomposer.org):
3737
`composer require indy2kro/php-iso`
3838

39+
CLI tool
40+
------------
41+
42+
This tool also provides a CLI tool that can be used to view information about ISO files - `bin\isotool`:
43+
```
44+
Description:
45+
Tool to process ISO files
46+
47+
Usage:
48+
isotool --file=<path>
49+
50+
Options:
51+
-f, --file Path for the ISO file (mandatory)
52+
```
53+
54+
Sample usage:
55+
```
56+
Input ISO file: fixtures/1mb.iso
57+
58+
Number of descriptors: 3
59+
- Primary volume descriptor
60+
- System ID: Win32
61+
- Volume ID: 25_12_2024
62+
- App ID: PowerISO
63+
- Volume Space Size: 542
64+
- Volume Set Size: 1
65+
- Volume SeqNum: 1
66+
- Block size: 2048
67+
- Volume Set ID:
68+
- Publisher ID:
69+
- Preparer ID:
70+
- Copyright File ID:
71+
- Abstract File ID:
72+
- Bibliographic File ID:
73+
- Creation Date: 2024-12-25 14:01:20
74+
- Modification Date: 2024-12-25 14:01:20
75+
- Expiration Date:
76+
- Effective Date:
77+
- Files:
78+
.
79+
..
80+
1MB.PNG
81+
82+
- Supplementary volume descriptor
83+
- System ID: Win32
84+
- Volume ID: 25_12_2024
85+
- App ID: PowerISO
86+
- Volume Space Size: 542
87+
- Volume Set Size: 1
88+
- Volume SeqNum: 1
89+
- Block size: 2048
90+
- Volume Set ID:
91+
- Publisher ID:
92+
- Preparer ID:
93+
- Copyright File ID: ?
94+
- Abstract File ID: ?
95+
- Bibliographic File ID: ?
96+
- Creation Date: 2024-12-25 14:01:20
97+
- Modification Date: 2024-12-25 14:01:20
98+
- Expiration Date:
99+
- Effective Date:
100+
- Files:
101+
.
102+
..
103+
1mb.png
104+
105+
- Terminator descriptor
106+
107+
```
39108

40109
Usage
41110
-----

bin/isotool

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
declare(strict_types=1);
5+
6+
use PhpIso\Cli\IsoTool;
7+
8+
(static function () {
9+
require_once dirname(__FILE__, 2) . '/vendor/autoload.php';
10+
11+
$application = new IsoTool();
12+
$application->run();
13+
})();

bin/isotool.bat

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@ECHO OFF
2+
setlocal DISABLEDELAYEDEXPANSION
3+
SET BIN_TARGET=%~dp0/isotool
4+
php "%BIN_TARGET%" %*

composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,8 @@
3838
},
3939
"optimize-autoloader": true,
4040
"sort-packages": true
41-
}
41+
},
42+
"bin": [
43+
"bin/isotool"
44+
]
4245
}

composer.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/IsoTool.php

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpIso\Cli;
6+
7+
use PhpIso\Descriptor;
8+
use PhpIso\Descriptor\Boot;
9+
use PhpIso\Descriptor\Volume;
10+
use PhpIso\Exception;
11+
use PhpIso\FileDirectory;
12+
use PhpIso\IsoFile;
13+
use PhpIso\PathTableRecord;
14+
use Throwable;
15+
16+
class IsoTool
17+
{
18+
public function run(): void
19+
{
20+
$options = $this->parseCliArgs();
21+
22+
if ($options === []) {
23+
$this->displayHelp();
24+
exit(1);
25+
}
26+
27+
$fileValue = $options['file'] ?? $options['f'];
28+
29+
$file = '';
30+
31+
if (is_array($fileValue)) {
32+
$file = current($fileValue);
33+
} elseif (is_string($fileValue)) {
34+
$file = $fileValue;
35+
}
36+
37+
if (! is_string($file) || $file === '') {
38+
$this->displayError('Invalid value for file received');
39+
exit(2);
40+
}
41+
42+
echo 'Input ISO file: ' . $file . PHP_EOL;
43+
44+
try {
45+
$this->checkIsoFile($file);
46+
$this->infoAction($file);
47+
} catch (Throwable $ex) {
48+
$this->displayError($ex->getMessage());
49+
exit(3);
50+
}
51+
}
52+
53+
protected function checkIsoFile(string $file): void
54+
{
55+
if (! file_exists($file)) {
56+
throw new Exception('ISO file does not exist.');
57+
}
58+
59+
if (! is_file($file)) {
60+
throw new Exception('Path is not a valid file.');
61+
}
62+
}
63+
64+
protected function infoAction(string $file): void
65+
{
66+
$isoFile = new IsoFile($file);
67+
68+
echo PHP_EOL;
69+
70+
echo 'Number of descriptors: ' . count($isoFile->descriptors) . PHP_EOL;
71+
72+
/** @var Descriptor $descriptor */
73+
foreach ($isoFile->descriptors as $descriptor) {
74+
echo ' - ' . $descriptor->name . PHP_EOL;
75+
76+
if ($descriptor instanceof Volume) {
77+
$this->infoVolume($descriptor);
78+
$this->displayFiles($descriptor, $isoFile);
79+
} elseif ($descriptor instanceof Boot) {
80+
$this->infoBoot($descriptor);
81+
}
82+
83+
echo PHP_EOL;
84+
}
85+
}
86+
87+
protected function infoVolume(Volume $volumeDescriptor): void
88+
{
89+
echo ' - System ID: ' . $volumeDescriptor->systemId . PHP_EOL;
90+
echo ' - Volume ID: ' . $volumeDescriptor->volumeId . PHP_EOL;
91+
echo ' - App ID: ' . $volumeDescriptor->appId . PHP_EOL;
92+
echo ' - Volume Space Size: ' . $volumeDescriptor->volumeSpaceSize . PHP_EOL;
93+
echo ' - Volume Set Size: ' . $volumeDescriptor->volumeSetSize . PHP_EOL;
94+
echo ' - Volume SeqNum: ' . $volumeDescriptor->volumeSeqNum . PHP_EOL;
95+
echo ' - Block size: ' . $volumeDescriptor->blockSize . PHP_EOL;
96+
echo ' - Volume Set ID: ' . $volumeDescriptor->volumeSetId . PHP_EOL;
97+
echo ' - Publisher ID: ' . $volumeDescriptor->publisherId . PHP_EOL;
98+
echo ' - Preparer ID: ' . $volumeDescriptor->preparerId . PHP_EOL;
99+
echo ' - Copyright File ID: ' . $volumeDescriptor->copyrightFileId . PHP_EOL;
100+
echo ' - Abstract File ID: ' . $volumeDescriptor->abstractFileId . PHP_EOL;
101+
echo ' - Bibliographic File ID: ' . $volumeDescriptor->bibliographicFileId . PHP_EOL;
102+
echo ' - Creation Date: ' . $volumeDescriptor->creationDate?->toDateTimeString() . PHP_EOL;
103+
echo ' - Modification Date: ' . $volumeDescriptor->modificationDate?->toDateTimeString() . PHP_EOL;
104+
echo ' - Expiration Date: ' . $volumeDescriptor->expirationDate?->toDateTimeString() . PHP_EOL;
105+
echo ' - Effective Date: ' . $volumeDescriptor->effectiveDate?->toDateTimeString() . PHP_EOL;
106+
}
107+
108+
protected function displayFiles(Volume $volumeDescriptor, IsoFile $isoFile): void
109+
{
110+
$pathTable = $volumeDescriptor->loadTable($isoFile);
111+
112+
if ($pathTable === null) {
113+
return;
114+
}
115+
116+
echo ' - Files:' . PHP_EOL;
117+
118+
/** @var PathTableRecord $pathRecord */
119+
foreach ($pathTable as $pathRecord) {
120+
// check extents
121+
$extents = $pathRecord->loadExtents($isoFile, $volumeDescriptor->blockSize);
122+
123+
if ($extents !== false) {
124+
/** @var FileDirectory $extentRecord */
125+
foreach ($extents as $extentRecord) {
126+
$path = $extentRecord->fileId;
127+
if ($extentRecord->isDirectory() && ! $extentRecord->isThis() && ! $extentRecord->isParent()) {
128+
$path .= '/';
129+
}
130+
echo $path . PHP_EOL;
131+
}
132+
}
133+
}
134+
}
135+
136+
protected function infoBoot(Boot $bootDescriptor): void
137+
{
138+
echo ' - Boot System ID: ' . $bootDescriptor->bootSysId . PHP_EOL;
139+
echo ' - Boot ID: ' . $bootDescriptor->bootId . PHP_EOL;
140+
echo ' - Boot Catalog Location: ' . $bootDescriptor->bootCatalogLocation . PHP_EOL;
141+
}
142+
143+
/**
144+
* @return array<string, mixed>
145+
*/
146+
protected function parseCliArgs(): array
147+
{
148+
$shortopts = 'f:';
149+
$longopts = [
150+
'file:',
151+
];
152+
$options = getopt($shortopts, $longopts, $restIndex);
153+
154+
if ($options === false) {
155+
return [];
156+
}
157+
158+
return $options;
159+
}
160+
161+
protected function displayError(string $error): void
162+
{
163+
echo 'ERROR: ' . $error . PHP_EOL;
164+
}
165+
166+
protected function displayHelp(): void
167+
{
168+
$help = '
169+
Description:
170+
Tool to process ISO files
171+
172+
Usage:
173+
isotool [options] --file=<path>
174+
175+
Options:
176+
-f, --file Path for the ISO file (mandatory)
177+
';
178+
echo $help;
179+
}
180+
}

src/Descriptor/UdfDescriptor.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
namespace PhpIso\Descriptor;
66

7+
use PhpIso\Descriptor;
78
use PhpIso\IsoFile;
89

9-
abstract class UdfDescriptor extends Volume
10+
abstract class UdfDescriptor extends Descriptor
1011
{
1112
public function init(IsoFile $isoFile, int &$offset): void
1213
{

0 commit comments

Comments
 (0)