ark: autodetect date order

unzip-6 can be configured at build time to return date in several
different fromats. There is no easy way to query unzip itself which one
it uses, but in the wild only to formats were seen: MM-DD-YYYY (default
for *nix) and YYYY-MM-DD (some linux distros; e.g. debian). So we will
be guestimating before those two.

Generic Arch class is not flexible enough, so it was necessary to
override whole processLine() and parse everything with RegExes.

Closes: https://mirror.git.trinitydesktop.org/gitea/TDE/tdeutils/issues/115
See-also: https://mirror.git.trinitydesktop.org/gitea/TDE/tdeutils/pulls/102
Signed-off-by: Alexander Golubev <fatzer2@gmail.com>
(cherry picked from commit 14d84907a0)
(cherry picked from commit 9e80634e0d)
(cherry picked from commit 1ddc8e16d8)
r14.1.x
mio 11 months ago committed by Alexander Golubev
parent 35e04f0c63
commit 21eecbb7c5

@ -28,6 +28,7 @@
// TQt includes
#include <tqdir.h>
#include <tqtextcodec.h>
// KDE includes
#include <kdebug.h>
@ -39,8 +40,10 @@
// ark includes
#include "zip.h"
#include "arkutils.h"
#include "arkwidget.h"
#include "settings.h"
#include "filelistview.h"
ZipArch::ZipArch( ArkWidget *_gui, const TQString & _fileName )
@ -51,70 +54,8 @@ ZipArch::ZipArch( ArkWidget *_gui, const TQString & _fileName )
verifyCompressUtilityIsAvailable( m_archiver_program );
verifyUncompressUtilityIsAvailable( m_unarchiver_program );
// Compatibility with unzip v5 and v6.
// - unzip 5 prints dates as MM-DD-YY.
// - unzip 6 prints dates as YYYY-MM-DD.
// Presume version 6 as it was released in 2009.
bool unzipV5 = false;
if (m_bUnarchUtilityIsAvailable)
{
KProcIO proc;
proc << m_unarchiver_program;
proc << "-v";
if (proc.start(KProcIO::Block))
{
proc.wait();
if (proc.normalExit() && proc.exitStatus() == 0)
{
TQString line;
proc.readln(line);
auto parts = TQStringList::split(' ', line);
unzipV5 = (parts.size() >= 2) && (parts[1][0] == '5');
}
}
}
m_headerString = "----";
m_fixTime = 10;
m_dateCol = 5;
m_numCols = 7;
if (unzipV5)
{
kdDebug(1601) << "ZipArch: unzip v5 detected." << endl;
m_repairYear = 9;
m_fixMonth = 7;
m_fixDay = 8;
}
else
{
m_fixYear = 7;
m_fixMonth = 8;
m_fixDay = 9;
}
m_archCols.append( new ArchColumns( 1, TQRegExp( "[0-9]+" ) ) );
m_archCols.append( new ArchColumns( 2, TQRegExp( "[^\\s]+" ) ) );
m_archCols.append( new ArchColumns( 3, TQRegExp( "[0-9]+" ) ) );
m_archCols.append( new ArchColumns( 4, TQRegExp( "[0-9.]+%" ) ) );
if (unzipV5)
{
m_archCols.append( new ArchColumns( 7, TQRegExp( "[01][0-9]" ), 2 ) );
m_archCols.append( new ArchColumns( 8, TQRegExp( "[0-3][0-9]" ), 2 ) );
m_archCols.append( new ArchColumns( 9, TQRegExp( "[0-9][0-9]" ), 2 ) );
}
else
{
m_archCols.append( new ArchColumns( 7, TQRegExp( "[0-9]{4}" ), 4 ) );
m_archCols.append( new ArchColumns( 8, TQRegExp( "[01][0-9]" ), 2 ) );
m_archCols.append( new ArchColumns( 9, TQRegExp( "[0-3][0-9]" ), 2 ) );
}
m_archCols.append( new ArchColumns( 10, TQRegExp( "[0-9:]+" ), 6 ) );
m_archCols.append( new ArchColumns( 6, TQRegExp( "[a-fA-F0-9]+ {2}" ) ) );
m_archCols.append( new ArchColumns( 0, TQRegExp( "[^\\n]+" ), 4096 ) );
}
void ZipArch::setHeaders()
@ -359,4 +300,62 @@ void ZipArch::test()
}
}
bool ZipArch::processLine( const TQCString &line )
{
TQTextCodec *codec = TQTextCodec::codecForLocale();
TQString tqunicode_line = codec->toUnicode( line );
// Header structure:
// Length Method Size Cmpr Date Time CRC-32 Name
// -------- ------ ------- ---- ---------- ----- -------- ----
TQRegExp lineRx { "^"
"\\s*" "(" "[0-9]+" ")" // 1 Length
"\\s+" "(" "\\S+" ")" // 2 Method
"\\s+" "(" "[0-9]+" ")" // 3 Size
"\\s+" "(" "[0-9.]+%" ")" // 4 Compression rate
"\\s+" "(" "[0-9\\-]+" ")" // 5 Date
"\\s+" "(" "[0-9:]+" ")" // 6 Time
"\\s+" "(" "[a-fA-F0-9]+" ")" // 7 CRC-32
" " "(" "[^\\n]+" ")" // 8 Name
"\\n?$"
};
if( lineRx.search(tqunicode_line) == -1 ) {
kdDebug(1601) << "processLine failed to match unzip line: " << line << endl;
return false;
}
// unzip can be configured at build time to return date in either of three
// formats (for version 6):
// - MM-DD-YYYY (the default on *nix systems)
// - DD-MM-YYYY (not used by default)
// - YYYY-MM-DD (used in several linux distribution e.g. debian)
// Unfortunately there is no easy way to query unzip which format it does
// use, so we will have to guestimate here. Also since the DMY is not widely
// used and in general case indistinguishable from MDY we will ignore it and
// concentrate on distinguishing between MDY and YMD. Luckily unzip-6 uses
// 4 digits for years, so it will be relatively painless. On the other hand
// unzip-5 uses 2-digits for a year, so in that case always assume MDY.
TQString date = lineRx.cap(5);
TQString time = lineRx.cap(6);
TQRegExp mdyDateRx{"^([01][0-9])-([0-3][0-9])-([0-9]{2,})$"};
if(mdyDateRx.search(date) != -1) {
date = ArkUtils::fixYear(mdyDateRx.cap(3)) + "-" + mdyDateRx.cap(1) + "-" + mdyDateRx.cap(2);
}
TQString timestamp = date + " " + time;
TQStringList l;
l << lineRx.cap(8); // FILENAME_COLUMN
l << lineRx.cap(1); // SIZE_COLUMN
l << lineRx.cap(2); // METHOD_COLUMN
l << lineRx.cap(3); // PACKED_COLUMN
l << lineRx.cap(4); // RATIO_COLUMN
l << timestamp; // TIMESTAMP_COLUMN
l << lineRx.cap(7); // CRC_COLUMN
m_gui->fileList()->addItem(l);
return true;
}
#include "zip.moc"

@ -54,6 +54,10 @@ class ZipArch : public Arch
virtual void unarchFileInternal();
virtual bool passwordRequired();
virtual void createPassword();
protected:
virtual bool processLine( const TQCString &line );
private:
void setHeaders();
};

Loading…
Cancel
Save