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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
//! mi - Stack viewer for Akiba OS
const colors = @import("colors");
const format = @import("format");
const io = @import("io");
const params = @import("params");
const sys = @import("sys");
const PERM_OWNER: u8 = 1;
const PERM_WORLD: u8 = 2;
const PERM_READ_ONLY: u8 = 3;
export fn main(pc: u32, pv: [*]const [*:0]const u8) u8 {
const p = params.parse(pc, pv) catch |err| {
format.color("mi: ", colors.red);
format.println(@errorName(err));
return 1;
};
var target_path: []const u8 = "";
if (p.positionals.len > 1) {
format.colorln("mi: invalid number of positional parameters.", colors.red);
return 1;
}
if (p.named.len > 0) {
format.colorln("mi: named parameters are not supported.", colors.red);
return 1;
}
if (p.positional(0)) |val| {
switch (val) {
.scalar => |s| target_path = s,
.list => {
format.colorln("mi: only one location allowed", colors.red);
return 1;
},
}
}
display_stack(target_path) catch {
return 1;
};
return 0;
}
fn display_stack(path: []const u8) !void {
var entries: [128]io.StackEntry = undefined;
const count = io.viewstack(path, &entries) catch {
format.color("mi: cannot access '", colors.red);
format.print(path);
format.colorln("': No such stack.", colors.red);
return error.Failed;
};
if (count == 0) {
format.color(path, colors.cyan);
format.colorln(" is empty.", colors.gray);
return;
}
var table = format.Table.init(&[_]format.Column{
.{ .name = "Access", .color = colors.cyan },
.{ .name = "Size", .color = colors.green },
.{ .name = "Persona", .color = colors.yellow },
.{ .name = "Modified", .color = colors.blue },
.{ .name = "Name", .color = colors.white },
});
var stack_count: usize = 0;
var unit_count: usize = 0;
var total_size: u64 = 0;
var size_bufs: [128][32]u8 = undefined;
var date_bufs: [128][32]u8 = undefined;
var name_bufs: [128][65]u8 = undefined;
for (0..count) |i| {
const entry = &entries[i];
const perms = get_permissions(entry.permission_type);
const size_str = format.formatSize(entry.size, &size_bufs[i]);
const date_str = format.formatDate(entry.modified_time, &date_bufs[i]);
const owner = entry.owner_name[0..entry.owner_name_len];
const identity = entry.identity[0..entry.identity_len];
// Build name with optional /
var name_len: usize = identity.len;
@memcpy(name_bufs[i][0..identity.len], identity);
if (entry.is_stack) {
name_bufs[i][name_len] = '/';
name_len += 1;
stack_count += 1;
} else {
unit_count += 1;
}
total_size += entry.size;
const name_color: u32 = if (entry.is_stack) colors.cyan else colors.white;
table.rowColored(
&[_][]const u8{ perms, size_str, owner, date_str, name_bufs[i][0..name_len] },
&[_]u32{ colors.cyan, colors.green, colors.yellow, colors.blue, name_color },
);
}
table.print();
format.print("\n");
var buf: [16]u8 = undefined;
format.color(format.intToStr(stack_count, &buf), colors.gray);
format.color(" stacks ", colors.gray);
format.color(format.intToStr(unit_count, &buf), colors.gray);
format.color(" units ", colors.gray);
var size_buf: [32]u8 = undefined;
format.colorln(format.formatSize(total_size, &size_buf), colors.gray);
}
fn get_permissions(perm_type: u8) []const u8 {
return switch (perm_type) {
PERM_OWNER => "Owner",
PERM_WORLD => "World",
PERM_READ_ONLY => "Read Only",
else => "Owner",
};
}
|