summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2024-10-23 21:14:22 +0200
committerTomas Bzatek <tbzatek@redhat.com>2024-10-23 21:14:22 +0200
commit40a71ffb604413c41b429dbbe4dfaf4520a03061 (patch)
treeea2abc1839cca441e4242667c35acee461515033
parentaf25c37af9cd3fd62b70ef2f238cbb900dd480e3 (diff)
downloadtuxcmd-40a71ffb604413c41b429dbbe4dfaf4520a03061.tar.xz
Sort global filelist in case of a streaming type archive
Before this change sorting was done on each panel item separately. Streaming type archives (e.g. tar) needs strict sequential order as indicated by the inode_no and the global filelist to copy needs to be sorted once more. Tested on 7z2301-extra.7z
-rw-r--r--UCore.pas42
-rw-r--r--UCoreWorkers.pas6
2 files changed, 30 insertions, 18 deletions
diff --git a/UCore.pas b/UCore.pas
index 79fcd32..9059371 100644
--- a/UCore.pas
+++ b/UCore.pas
@@ -29,6 +29,7 @@ procedure FindNextSelected(ListView: TGTKListView; DataList: TList; var Item1, I
procedure UnselectAll(ListView: TGTKListView; DataList: TList);
procedure FillDirFiles(Engine: TPanelEngine; DestList: TList; InputFiles: TStringList; DoNotRecurse: boolean; InaccessiblePaths: TStringList; CancelFlag: Pboolean);
+procedure FillDirFiles_sort(FList: TList);
function GetFileInfoSL(Engine: TPanelEngine; const APath: string): PDataItemSL;
procedure DebugWriteListSL(List: TList);
@@ -348,8 +349,7 @@ end;
(********************************************************************************************************************************)
(********************************************************************************************************************************)
-procedure FillDirFiles(Engine: TPanelEngine; DestList: TList; InputFiles: TStringList; DoNotRecurse: boolean; InaccessiblePaths: TStringList; CancelFlag: Pboolean);
-var DirStage1List, FilesList, DirStage2List: TList;
+procedure FillDirFiles_sort(FList: TList);
function FillDirFiles_compare_func(Item1, Item2: Pointer): integer;
var DataItem1, DataItem2: PDataItem;
@@ -357,12 +357,16 @@ var DirStage1List, FilesList, DirStage2List: TList;
DataItem1 := PDataItemSL(Item1)^.DataItem;
DataItem2 := PDataItemSL(Item2)^.DataItem;
// sort by inode number
- // also, we want to have directories at the bottom of the list
- if DataItem1^.IsDir and (not DataItem2^.IsDir) then Result := 1 else
- if (not DataItem1^.IsDir) and DataItem2^.IsDir then Result := -1 else
+ // also, we want to have directories at the top of the list
+ if PDataItemSL(Item1)^.Stage1 and (not PDataItemSL(Item2)^.Stage1) then Result := -1 else
+ if (not PDataItemSL(Item1)^.Stage1) and PDataItemSL(Item2)^.Stage1 then Result := 1 else
+ if DataItem1^.IsDir and (not DataItem2^.IsDir) then Result := -1 else
+ if (not DataItem1^.IsDir) and DataItem2^.IsDir then Result := 1 else
if DataItem1^.inode_no > DataItem2^.inode_no then Result := 1 else
if DataItem1^.inode_no < DataItem2^.inode_no then Result := -1 else
- Result := 0;
+ // sort by name, in inverse order for Stage2
+ if PDataItemSL(Item1)^.Stage1 then Result := strcmp(DataItem1^.FName, DataItem2^.FName)
+ else Result := -strcmp(DataItem1^.FName, DataItem2^.FName);
end;
procedure QuickSort(FList: TList; L, R : Longint);
@@ -392,18 +396,20 @@ var DirStage1List, FilesList, DirStage2List: TList;
until I >= R;
end;
- procedure FillDirFiles_sort(FList: TList);
- var i: integer;
- begin
- if FList.Count < 2 then Exit;
- DebugMsg(['before sorting:']);
- for i := 0 to FList.Count - 1 do
- DebugMsg([' ', i, ' [', PDataItemSL(FList[i])^.DataItem^.inode_no, '] ', PDataItemSL(FList[i])^.DataItem^.FName]);
- QuickSort(Flist, 0, FList.Count - 1);
- DebugMsg(['after sorting:']);
- for i := 0 to FList.Count - 1 do
- DebugMsg([' ', i, ' [', PDataItemSL(FList[i])^.DataItem^.inode_no, '] ', PDataItemSL(FList[i])^.DataItem^.FName]);
- end;
+var i: integer;
+begin
+ if FList.Count < 2 then Exit;
+ DebugMsg(['before sorting:']);
+ for i := 0 to FList.Count - 1 do
+ DebugMsg([' ', i, ' [', PDataItemSL(FList[i])^.DataItem^.inode_no, '] ', PDataItemSL(FList[i])^.DataItem^.FName]);
+ QuickSort(Flist, 0, FList.Count - 1);
+ DebugMsg(['after sorting:']);
+ for i := 0 to FList.Count - 1 do
+ DebugMsg([' ', i, ' [', PDataItemSL(FList[i])^.DataItem^.inode_no, '] ', PDataItemSL(FList[i])^.DataItem^.FName]);
+end;
+
+procedure FillDirFiles(Engine: TPanelEngine; DestList: TList; InputFiles: TStringList; DoNotRecurse: boolean; InaccessiblePaths: TStringList; CancelFlag: Pboolean);
+var DirStage1List, FilesList, DirStage2List: TList;
procedure FillDirFiles_Recurse(const LocalPath: string; ALevel: integer);
var LocalList: TList;
diff --git a/UCoreWorkers.pas b/UCoreWorkers.pas
index 6ea4268..507e2b7 100644
--- a/UCoreWorkers.pas
+++ b/UCoreWorkers.pas
@@ -1501,6 +1501,12 @@ begin
{ if DestEngine.ChangeDir(CurrPath) <> 0 then DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour may occur.']);
if SrcEngine.ChangeDir(CurrPath) <> 0 then DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour may occur.']); }
+
+ // For streaming type archives the list of files to copy strictly needs to be sorted globally according to inode_no
+ if (SrcEngine is TVFSEngine) and (SrcEngine as TVFSEngine).ArchiveMode and (SrcEngine as TVFSEngine).ArchiveStreamingType then begin
+ DebugMsg(['Archive type is streaming, performing global filelist sort...']);
+ FillDirFiles_sort(List);
+ end;
DebugWriteListSL(List);
SkipInaccessible := False;