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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
//! Viewstack invocation - List contents of a stack
const afs = @import("../../fs/afs/afs.zig");
const ahci = @import("../../drivers/ahci/ahci.zig");
const copy = @import("../../utils/mem/copy.zig");
const fs_limits = @import("../../common/limits/fs.zig");
const handler = @import("../handler.zig");
const int = @import("../../utils/types/int.zig");
const location = @import("../../utils/fs/location.zig");
const memory_limits = @import("../../common/limits/memory.zig");
const ptr = @import("../../utils/types/ptr.zig");
const result = @import("../../utils/types/result.zig");
const sensei = @import("../../kata/sensei/sensei.zig");
const slice = @import("../../utils/mem/slice.zig");
const MAX_ENTRY_IDENTITY: usize = 64;
const MAX_ENTRY_OWNER: usize = 64;
const UserStackEntry = extern struct {
identity: [MAX_ENTRY_IDENTITY]u8,
identity_len: u8,
is_stack: bool,
owner_name_len: u8,
permission_type: u8,
size: u32,
modified_time: u64,
owner_name: [MAX_ENTRY_OWNER]u8,
};
var afs_instance: ?*afs.AFS(ahci.BlockDevice) = null;
pub fn set_afs_instance(fs: *afs.AFS(ahci.BlockDevice)) void {
afs_instance = fs;
}
pub fn invoke(ctx: *handler.InvocationContext) void {
const fs = afs_instance orelse return result.set_error(ctx);
const location_ptr = ctx.rdi;
const location_len = ctx.rsi;
const entries_ptr = ctx.rdx;
const max_entries = ctx.r10;
if (!memory_limits.is_valid_kata_pointer(location_ptr) or !memory_limits.is_valid_kata_pointer(entries_ptr)) {
return result.set_error(ctx);
}
if (location_len > fs_limits.MAX_LOCATION_LENGTH) return result.set_error(ctx);
var location_buf: [fs_limits.MAX_LOCATION_LENGTH]u8 = undefined;
copy.from_ptr(&location_buf, location_ptr, location_len);
const loc = location_buf[0..location_len];
const kata = sensei.get_current_kata();
const current_cluster: u64 = if (kata) |k| k.current_cluster else 0;
const target_cluster = location.resolve_to_cluster(fs, loc, current_cluster) orelse {
return result.set_error(ctx);
};
var items: [fs_limits.MAX_STACK_ITEMS]afs.StackItem = undefined;
const item_count = fs.list_stack(target_cluster, &items) catch return result.set_error(ctx);
const user_entries = slice.typed_ptr(UserStackEntry, entries_ptr);
const copy_count = @min(item_count, max_entries);
for (0..copy_count) |i| {
const item = &items[i];
var user_entry = &user_entries[i];
const identity = item.get_identity();
const id_len = @min(identity.len, MAX_ENTRY_IDENTITY - 1);
copy.bytes(user_entry.identity[0..id_len], identity[0..id_len]);
user_entry.identity_len = @intCast(id_len);
user_entry.size = item.size;
user_entry.is_stack = item.is_stack;
user_entry.modified_time = item.modified_time;
const owner = item.get_owner();
const owner_len = @min(owner.len, MAX_ENTRY_OWNER - 1);
copy.bytes(user_entry.owner_name[0..owner_len], owner[0..owner_len]);
user_entry.owner_name_len = @intCast(owner_len);
user_entry.permission_type = item.permission_type;
}
result.set_value(ctx, copy_count);
}
|