Gemorroj / Archive7z

This library provides handling of 7z files in PHP
GNU Lesser General Public License v3.0
89 stars 20 forks source link

Reading previously divided archives #36

Open web-masta opened 8 months ago

web-masta commented 8 months ago

Hello and thank you for this cool tool!

I have a problem with reading contents of divided into parts archives. The command is failing, however showing some contents.

File names are stored as hash values.

Is there a simple solution to, maybe, ignore or fix this type of error without archive modification? The process is failing before I can catch it in an easy way.

Example output:

The command "'/usr/bin/7z' 'l' '/home/www/var/files/DB0/hash/f8/01/7c78e011b8ca53015b' '-slt' '-y' '-p '" failed.
Exit Code: 2(Misuse of shellbuiltins)
Working directory: /home/www

Output:                                                                                                                                                                        
================                                                                                                                                                               
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov :2016-05-21
p7zip Version 16.02 (locale=C,Utf16=off,HugeFiles=on,64 bits,8 CPUs Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz (906E9),ASM,AES-NI)

Scanning the drive for archives:
1 file, 220200960 bytes (210 MiB)

Listing archive: /home/www/var/files/DB0/hash/f8/01/7c78e011b8ca53015b
--                                                                                                                                                                             
Path = /home/www/var/files/DB0/hash/f8/01/7c78e011b8ca53015b
Type = Rar
ERROR = Missing volume : f801b604de805be59b0b7d61288e3811ef31d6e9e091777c78e011b8ca53015b.r00
Physical Size = 220200960
Characteristics = Volume NewVolName FirstVolume VolCRC
Solid = -
Blocks = 1
Multivolume = +
Volume Index = 0
Volumes = 1
 ----------                                                                                                                                                                     
Path = setup_Full.exe
Folder = -
Size = 438531863
Packed Size = 220200861
Modified = 2008-09-09 12:52:34
Created =
Accessed =
Attributes = A
Encrypted = -
Solid = -
Commented = -
Split Before = -
Split After = +
CRC = 1B0C199D
Host OS = Win32
Method = m0:22
Version = 20

Errors: 1
Gemorroj commented 8 months ago

@web-masta can you provide php code example?

web-masta commented 8 months ago
        try {
            $archiveObject = new Archive7z($filePath);
        } catch (\Throwable $e) {
            $message = sprintf("Archive7z error, could not open file %d: %s",$file->id, $e->getMessage());
            throw new FileException($message, $e->getCode(), $e);
        }

        try {
            $entries = $archiveObject->getEntries();
        } catch (\Throwable $e) {
            $message = sprintf("Archive7z entries read error, file %d: %s", $file->id, $e->getMessage());
            throw new FileException($message, $e->getCode(), $e);
        }
        ...

Failing while trying to getEntries() (and most of other methods as well) before it goes to catch.

Gemorroj commented 8 months ago

@web-masta and what kind of behavior do you expect? At first glance, the behavior is correct. If the rest of the archive is in the directory, there will be no error.

web-masta commented 8 months ago

I expect to somehow get the list of contents of those files. But I can see entries only in error message.

The problem is that different parts of archives can be uploaded in different directories, or even on different disks. This whole system of uploading was made ages ago and back then there was no need to look inside archives.

Gemorroj commented 8 months ago

@web-masta but this will only be a partial list of files. falling into a part of the archive. you can ignore some exit codes and the partial list will work:

<?php
use Archive7z\Archive7z;

class MyArchive7z extends Archive7z
{
    protected function execute(Process $process): Process
    {
        $exitCode = $process->run();
        if ($exitCode > 2) {
            throw new ProcessFailedException($process);
        }
        return $process;
    }
}
web-masta commented 8 months ago

Thank you! I will try this out.