Repository navigation
Expand file tree
/
Copy pathtardefs.zig
More file actions
67 lines (54 loc) · 2.08 KB
/
Copy pathtardefs.zig
File metadata and controls
67 lines (54 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
const std = @import("std");
pub const block_size = 512;
pub const PosixMagic = extern struct {
magic: [6]u8, // POSIX tar magic number
version: [2]u8, // POSIX tar version
const ref_magic = "ustar" ++ .{0};
pub fn isValid(self: PosixMagic) bool {
return std.mem.eql(u8, &self.magic, PosixMagic.ref_magic);
}
};
pub const GnuMagic = extern struct {
magic: [8]u8, // GNU tar magic number
const ref_magic = "ustar " ++ .{0};
pub fn isValid(self: GnuMagic) bool {
return std.mem.eql(u8, &self.magic, GnuMagic.ref_magic);
}
};
pub const Magic = extern union { posix: PosixMagic, gnu: GnuMagic };
pub const TarHeader = struct {
name: [100]u8, // File name
mode: [8]u8, // File mode (octal ASCII)
uid: [8]u8, // Owner user ID (octal ASCII)
gid: [8]u8, // Owner group ID (octal ASCII)
size: [12]u8, // File size in bytes (octal ASCII)
mtime: [12]u8, // Modification time (octal ASCII)
chksum: [8]u8, // Checksum (ASCII space‑filled for sum calculation)
typeflag: u8, // File type indicator
linkname: [100]u8, // Name of linked file (for hard/sym links)
magic: Magic, // Magic number (POSIX or GNU)
uname: [32]u8, // Owner user name
gname: [32]u8, // Owner group name
devmajor: [8]u8, // Device major number (for character/block devices)
devminor: [8]u8, // Device minor number
prefix: [155]u8, // Path prefix to allow 255‑byte names
pad: [12]u8, // Padding to fill 512 bytes
};
comptime {
std.debug.assert(@sizeOf(TarHeader) == block_size);
}
pub fn calcChecksum(header: *const TarHeader, comptime char_type: type) u32 {
var sum: u32 = ' ' * 8;
const header_bytes: *const [512]char_type = @ptrCast(header);
for (0..@offsetOf(TarHeader, "chksum")) |i| {
sum += @intCast(header_bytes[i]);
}
for (header_bytes[@offsetOf(TarHeader, "chksum") + 8 ..]) |c| {
sum += @intCast(c);
}
return sum;
}
pub fn isZeroBlock(header: *const TarHeader) bool {
const header_bytes: *const [512]u8 = @ptrCast(header);
return std.mem.allEqual(u8, header_bytes, 0);
}