[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH 3/4] Pascal-RTL: tar: Links entpacken
+ Pascal-RTL: tar: Unterstützung für harte und symbolische Links
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
src/modules/pas/lib/tar/tar.pas | 58 +++++++++++++++++++++++++++++++++++++++
1 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/src/modules/pas/lib/tar/tar.pas b/src/modules/pas/lib/tar/tar.pas
index 2faeee9..7ce475c 100644
--- a/src/modules/pas/lib/tar/tar.pas
+++ b/src/modules/pas/lib/tar/tar.pas
@@ -7,6 +7,7 @@ const
TAR_BUFFER_SIZE = 65536;
TAR_TYPE_FILE = '0';
+ TAR_TYPE_HARDLINK = '1';
TAR_TYPE_SYMLINK = '2';
TAR_TYPE_DIRECTORY = '5';
@@ -22,10 +23,12 @@ type
function NextFilename: String;
function NextSize: dword;
function NextFiletype: char;
+ function NextLinkTarget: String;
function ExtractString(silent: boolean = false): String;
procedure ExtractFile(var outfile: file);
+ procedure ExtractLink(basepath: String);
procedure SkipFile;
private
@@ -43,6 +46,24 @@ type
implementation
+{$IF DEFINED(LINUX)}
+uses baseunix;
+
+procedure c_io_create_link(target, link: PChar; hardlink: boolean);
+begin
+ if hardlink then begin
+ fpLink(target, link);
+ end else begin
+ fpSymlink(target, link);
+ end;
+end;
+{$ELSEIF DEFINED(TYNDUR)}
+procedure c_io_create_link(target, link: PChar; hardlink: boolean);
+ cdecl; external name 'io_create_link';
+{$ELSE}
+{$ERROR OS not supported!}
+{$ENDIF}
+
type
TTarFileHeader = packed record
name: array [1..100] of char;
@@ -153,6 +174,20 @@ begin
end;
end;
+function TTarArchive.NextLinkTarget: String;
+var
+ i: longint;
+begin
+ NextLinkTarget := PTarFileHeader(@buffer)^.link;
+
+ for i := 1 to 100 do begin
+ if NextLinkTarget[i] = #0 then begin
+ SetLength(NextLinkTarget, i - 1);
+ break;
+ end;
+ end;
+end;
+
function TTarArchive.NextSize: dword;
begin
NextSize := OctalToInt(PTarFileHeader(@buffer)^.size);
@@ -265,7 +300,30 @@ begin
WriteLn(#13, '[', filename, '] ', size, '/', size, ' Bytes entpackt');
FileDone;
+end;
+procedure TTarArchive.ExtractLink(basepath: String);
+var
+ target_fn, target_path: String;
+ link_fn, link_path: String;
+ hard: boolean;
+begin
+ if not (NextFiletype in [TAR_TYPE_SYMLINK, TAR_TYPE_HARDLINK]) then begin
+ exit;
+ end;
+
+ link_fn := NextFilename;
+ link_path := basepath + '/' + link_fn + #0;
+
+ target_fn := NextLinkTarget;
+ target_path := basepath + '/' + target_fn + #0;
+
+ hard := (NextFiletype = TAR_TYPE_HARDLINK);
+
+ c_io_create_link(@target_path[1], @link_path[1], hard);
+ WriteLn('[', link_fn, '] Link auf ' + target_fn + ' erstellt');
+
+ FileDone;
end;
procedure TTarArchive.SkipFile;
--
1.6.0.2