@@ -21,70 +21,12 @@ const testing = std.testing;
21
21
22
22
pub const output = @import ("tar/output.zig" );
23
23
24
- /// Provide this to receive detailed error messages.
25
- /// When this is provided, some errors which would otherwise be returned
26
- /// immediately will instead be added to this structure. The API user must check
27
- /// the errors in diagnostics to know whether the operation succeeded or failed.
28
- pub const Diagnostics = struct {
29
- allocator : std.mem.Allocator ,
30
- errors : std .ArrayListUnmanaged (Error ) = .{},
31
-
32
- pub const Error = union (enum ) {
33
- unable_to_create_sym_link : struct {
34
- code : anyerror ,
35
- file_name : []const u8 ,
36
- link_name : []const u8 ,
37
- },
38
- unable_to_create_file : struct {
39
- code : anyerror ,
40
- file_name : []const u8 ,
41
- },
42
- unsupported_file_type : struct {
43
- file_name : []const u8 ,
44
- file_type : Header.Kind ,
45
- },
46
- };
47
-
48
- pub fn deinit (d : * Diagnostics ) void {
49
- for (d .errors .items ) | item | {
50
- switch (item ) {
51
- .unable_to_create_sym_link = > | info | {
52
- d .allocator .free (info .file_name );
53
- d .allocator .free (info .link_name );
54
- },
55
- .unable_to_create_file = > | info | {
56
- d .allocator .free (info .file_name );
57
- },
58
- .unsupported_file_type = > | info | {
59
- d .allocator .free (info .file_name );
60
- },
61
- }
62
- }
63
- d .errors .deinit (d .allocator );
64
- d .* = undefined ;
65
- }
66
- };
67
-
68
24
/// pipeToFileSystem options
69
25
pub const PipeOptions = struct {
70
26
/// Number of directory levels to skip when extracting files.
71
27
strip_components : u32 = 0 ,
72
- /// How to handle the "mode" property of files from within the tar file.
73
- mode_mode : ModeMode = .executable_bit_only ,
74
28
/// Prevents creation of empty directories.
75
29
exclude_empty_directories : bool = false ,
76
- /// Collects error messages during unpacking
77
- diagnostics : ? * Diagnostics = null ,
78
-
79
- pub const ModeMode = enum {
80
- /// The mode from the tar file is completely ignored. Files are created
81
- /// with the default mode when creating files.
82
- ignore ,
83
- /// The mode from the tar file is inspected for the owner executable bit
84
- /// only. This bit is copied to the group and other executable bits.
85
- /// Other bits of the mode are left as the default when creating files.
86
- executable_bit_only ,
87
- };
88
30
};
89
31
90
32
const Header = struct {
@@ -247,16 +189,13 @@ pub const IteratorOptions = struct {
247
189
file_name_buffer : []u8 ,
248
190
/// Use a buffer with length `std.fs.MAX_PATH_BYTES` to match file system capabilities.
249
191
link_name_buffer : []u8 ,
250
- /// Collects error messages during unpacking
251
- diagnostics : ? * Diagnostics = null ,
252
192
};
253
193
254
194
/// Iterates over files in tar archive.
255
195
/// `next` returns each file in tar archive.
256
196
pub fn iterator (reader : anytype , options : IteratorOptions ) Iterator (@TypeOf (reader )) {
257
197
return .{
258
198
.reader = reader ,
259
- .diagnostics = options .diagnostics ,
260
199
.file_name_buffer = options .file_name_buffer ,
261
200
.link_name_buffer = options .link_name_buffer ,
262
201
};
@@ -273,7 +212,6 @@ pub const FileKind = enum {
273
212
pub fn Iterator (comptime ReaderType : type ) type {
274
213
return struct {
275
214
reader : ReaderType ,
276
- diagnostics : ? * Diagnostics = null ,
277
215
278
216
// buffers for heeader and file attributes
279
217
header_buffer : [Header .SIZE ]u8 = undefined ,
@@ -435,15 +373,11 @@ pub fn Iterator(comptime ReaderType: type) type {
435
373
},
436
374
// All other are unsupported header types
437
375
else = > {
438
- const d = self .diagnostics orelse return error .TarUnsupportedHeader ;
439
- try d .errors .append (d .allocator , .{ .unsupported_file_type = .{
440
- .file_name = try d .allocator .dupe (u8 , header .name ()),
441
- .file_type = kind ,
442
- } });
443
376
if (kind == .gnu_sparse ) {
444
377
try self .skipGnuSparseExtendedHeaders (header );
445
378
}
446
379
self .reader .skipBytes (size , .{}) catch return error .TarHeadersTooBig ;
380
+ return error .TarUnsupportedHeader ;
447
381
},
448
382
}
449
383
}
@@ -573,24 +507,11 @@ fn PaxIterator(comptime ReaderType: type) type {
573
507
574
508
/// Saves tar file content to the file systems.
575
509
pub fn pipeToFileSystem (dir : std.fs.Dir , reader : anytype , options : PipeOptions ) ! void {
576
- switch (options .mode_mode ) {
577
- .ignore = > {},
578
- .executable_bit_only = > {
579
- // This code does not look at the mode bits yet. To implement this feature,
580
- // the implementation must be adjusted to look at the mode, and check the
581
- // user executable bit, then call fchmod on newly created files when
582
- // the executable bit is supposed to be set.
583
- // It also needs to properly deal with ACLs on Windows.
584
- @panic ("TODO: unimplemented: tar ModeMode.executable_bit_only" );
585
- },
586
- }
587
-
588
510
var file_name_buffer : [std .fs .MAX_PATH_BYTES ]u8 = undefined ;
589
511
var link_name_buffer : [std .fs .MAX_PATH_BYTES ]u8 = undefined ;
590
512
var iter = iterator (reader , .{
591
513
.file_name_buffer = & file_name_buffer ,
592
514
.link_name_buffer = & link_name_buffer ,
593
- .diagnostics = options .diagnostics ,
594
515
});
595
516
while (try iter .next ()) | file | {
596
517
switch (file .kind ) {
@@ -605,16 +526,9 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions)
605
526
const file_name = stripComponents (file .name , options .strip_components );
606
527
if (file_name .len == 0 ) return error .BadFileName ;
607
528
608
- if (createDirAndFile (dir , file_name )) | fs_file | {
609
- defer fs_file .close ();
610
- try file .writeAll (fs_file );
611
- } else | err | {
612
- const d = options .diagnostics orelse return err ;
613
- try d .errors .append (d .allocator , .{ .unable_to_create_file = .{
614
- .code = err ,
615
- .file_name = try d .allocator .dupe (u8 , file_name ),
616
- } });
617
- }
529
+ var fs_file = try createDirAndFile (dir , file_name );
530
+ defer fs_file .close ();
531
+ try file .writeAll (fs_file );
618
532
},
619
533
.sym_link = > {
620
534
// The file system path of the symbolic link.
@@ -623,14 +537,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions)
623
537
// The data inside the symbolic link.
624
538
const link_name = file .link_name ;
625
539
626
- createDirAndSymlink (dir , link_name , file_name ) catch | err | {
627
- const d = options .diagnostics orelse return error .UnableToCreateSymLink ;
628
- try d .errors .append (d .allocator , .{ .unable_to_create_sym_link = .{
629
- .code = err ,
630
- .file_name = try d .allocator .dupe (u8 , file_name ),
631
- .link_name = try d .allocator .dupe (u8 , link_name ),
632
- } });
633
- };
540
+ try createDirAndSymlink (dir , link_name , file_name );
634
541
},
635
542
}
636
543
}
@@ -984,7 +891,6 @@ test pipeToFileSystem {
984
891
985
892
// Save tar from `reader` to the file system `dir`
986
893
pipeToFileSystem (dir , reader , .{
987
- .mode_mode = .ignore ,
988
894
.strip_components = 1 ,
989
895
.exclude_empty_directories = true ,
990
896
}) catch | err | {
0 commit comments