summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2022-04-25 05:09:55 +0300
committerGravatar Uko Kokņevičs2022-04-25 23:34:05 +0300
commitd303b53f2ced75703bf022a5d337ee3ba530b288 (patch)
treef2e64057120d01ee8a821596ea01b8fc37c53c2c /libs
downloadzup-0.1.0.tar.gz
zup-0.1.0.tar.xz
zup-0.1.0.zip
Initial commit0.1.0
Diffstat (limited to 'libs')
m---------libs/clap0
-rw-r--r--libs/curl/curl.zig103
-rw-r--r--libs/libarchive/libarchive.zig135
-rw-r--r--libs/xdg/xdg.zig36
4 files changed, 274 insertions, 0 deletions
diff --git a/libs/clap b/libs/clap
new file mode 160000
Subproject ac5f46541ca47d3db9df0fcef3cc61731adaefa
diff --git a/libs/curl/curl.zig b/libs/curl/curl.zig
new file mode 100644
index 0000000..4a26eed
--- /dev/null
+++ b/libs/curl/curl.zig
@@ -0,0 +1,103 @@
1pub const c = @cImport(@cInclude("curl/curl.h"));
2
3const std = @import("std");
4
5const Allocator = std.mem.Allocator;
6const ArrayList = std.ArrayList;
7const File = std.fs.File;
8
9pub fn easyDownload(allocator: Allocator, url: [:0]const u8) ![]u8 {
10 var handle = try Easy.init();
11 defer handle.deinit();
12
13 var buf = ArrayList(u8).init(allocator);
14 defer buf.deinit();
15
16 try handle.setopt(.url, url.ptr);
17 try handle.setopt(.follow_location, true);
18 try handle.setopt(.write_function, easyDownloadCb);
19 try handle.setopt(.write_data, &buf);
20
21 try handle.perform();
22
23 return buf.toOwnedSlice();
24}
25
26fn easyDownloadCb(ptr: [*]const u8, size: usize, nmemb: usize, buf: *ArrayList(u8)) usize {
27 std.debug.assert(size == 1);
28
29 const slice = ptr[0..nmemb];
30 buf.appendSlice(slice) catch |err| {
31 std.log.err("in easyDownloadCb: {}", .{err});
32 return 0;
33 };
34
35 return nmemb;
36}
37
38pub fn easyDownloadToFile(file: *File, url: [:0]const u8) !void {
39 var handle = try Easy.init();
40 defer handle.deinit();
41
42 const writer = file.writer();
43
44 try handle.setopt(.url, url.ptr);
45 try handle.setopt(.follow_location, true);
46 try handle.setopt(.write_function, easyDownloadToFileCb);
47 try handle.setopt(.write_data, &writer);
48
49 try handle.perform();
50}
51
52fn easyDownloadToFileCb(ptr: [*]const u8, size: usize, nmemb: usize, writer: *const File.Writer) usize {
53 std.debug.assert(size == 1);
54
55 const slice = ptr[0..nmemb];
56 writer.writeAll(slice) catch |err| {
57 std.log.err("in easyDownloadToFileCb: {}", .{err});
58 return 0;
59 };
60
61 return nmemb;
62}
63
64pub const Easy = struct {
65 raw: *c.CURL,
66
67 pub const Option = enum(c.CURLoption) {
68 follow_location = c.CURLOPT_FOLLOWLOCATION,
69 url = c.CURLOPT_URL,
70 write_data = c.CURLOPT_WRITEDATA,
71 write_function = c.CURLOPT_WRITEFUNCTION,
72 };
73
74 pub fn init() !Easy {
75 if (c.curl_easy_init()) |raw| {
76 return Easy{ .raw = raw };
77 } else {
78 return error.CurlError;
79 }
80 }
81
82 pub fn deinit(self: *Easy) void {
83 c.curl_easy_cleanup(self.raw);
84 self.* = undefined;
85 }
86
87 pub fn perform(self: *Easy) !void {
88 const errc = c.curl_easy_perform(self.raw);
89 if (errc != c.CURLE_OK) {
90 std.log.err("Curl: {s}", .{c.curl_easy_strerror(errc)});
91 return error.CurlError;
92 }
93 }
94
95 pub fn setopt(self: *Easy, option: Option, param: anytype) !void {
96 const option_raw = @enumToInt(option);
97 const errc = c.curl_easy_setopt(self.raw, option_raw, param);
98 if (errc != c.CURLE_OK) {
99 std.log.err("Curl: {s}", .{c.curl_easy_strerror(errc)});
100 return error.CurlError;
101 }
102 }
103};
diff --git a/libs/libarchive/libarchive.zig b/libs/libarchive/libarchive.zig
new file mode 100644
index 0000000..dab205e
--- /dev/null
+++ b/libs/libarchive/libarchive.zig
@@ -0,0 +1,135 @@
1pub const c = @cImport({
2 @cInclude("archive.h");
3 @cInclude("archive_entry.h");
4});
5
6const std = @import("std");
7
8pub const Entry = struct {
9 raw: *c.archive_entry,
10
11 pub fn pathname(self: Entry) [:0]const u8 {
12 return std.mem.span(c.archive_entry_pathname(self.raw));
13 }
14
15 pub fn setPathname(self: *Entry, new_pathname: [:0]const u8) void {
16 c.archive_entry_set_pathname(self.raw, new_pathname.ptr);
17 }
18};
19
20pub const Read = struct {
21 raw: *c.archive,
22
23 pub fn init() !Read {
24 if (c.archive_read_new()) |raw| {
25 return Read{ .raw = raw };
26 } else {
27 std.log.err("archive_read_new failed", .{});
28 return error.LibArchiveError;
29 }
30 }
31
32 pub fn deinit(self: *Read) void {
33 if (c.archive_read_free(self.raw) != c.ARCHIVE_OK) {
34 std.log.warn("archive_read_free failed", .{});
35 }
36 }
37
38 pub const Filter = enum {
39 all,
40 bzip2,
41 compress,
42 grzip,
43 gzip,
44 lrzip,
45 lz4,
46 lzma,
47 lzop,
48 none,
49 rpm,
50 uu,
51 xz,
52 zstd,
53 };
54
55 pub fn supportFilter(self: *Read, comptime filter: Filter) !void {
56 const fn_name = comptime "archive_read_support_filter_" ++ @tagName(filter);
57 const f = comptime @field(c, fn_name);
58 if (f(self.raw) != c.ARCHIVE_OK) {
59 std.log.err(fn_name ++ ": {s}", .{c.archive_error_string(self.raw)});
60 return error.LibArchiveError;
61 }
62 }
63
64 pub const Format = enum {
65 @"7zip",
66 all,
67 ar,
68 cab,
69 cpio,
70 empty,
71 iso9660,
72 lha,
73 mtree,
74 rar,
75 raw,
76 tar,
77 xar,
78 zip,
79 };
80
81 pub fn supportFormat(self: *Read, comptime format: Format) !void {
82 const fn_name = comptime "archive_read_support_format_" ++ @tagName(format);
83 const f = comptime @field(c, fn_name);
84 if (f(self.raw) != c.ARCHIVE_OK) {
85 std.log.err(fn_name ++ ": {s}", .{c.archive_error_string(self.raw)});
86 return error.LibArchiveError;
87 }
88 }
89
90 pub fn openFilename(self: *Read, filename: [:0]const u8, block_size: usize) !void {
91 if (c.archive_read_open_filename(self.raw, filename.ptr, block_size) != c.ARCHIVE_OK) {
92 std.log.err("archive_read_open_filename: {s}", .{c.archive_error_string(self.raw)});
93 return error.LibArchiveError;
94 }
95 }
96
97 pub fn nextHeader(self: *Read) !?Entry {
98 var header_raw: ?*c.archive_entry = undefined;
99 var r = c.ARCHIVE_RETRY;
100 while (r == c.ARCHIVE_RETRY) {
101 r = c.archive_read_next_header(self.raw, &header_raw);
102 }
103
104 if (r == c.ARCHIVE_WARN) {
105 std.log.warn("archive_read_next_header: {s}", .{c.archive_error_string(self.raw)});
106 r = c.ARCHIVE_OK;
107 }
108
109 if (r == c.ARCHIVE_EOF) {
110 return null;
111 }
112
113 if (r != c.ARCHIVE_OK or header_raw == null) {
114 std.log.err("archive_read_next_header: {s}", .{c.archive_error_string(self.raw)});
115 return error.LibArchiveError;
116 }
117
118 return Entry{ .raw = header_raw.? };
119 }
120
121 // TODO: Replace flags with enum
122 pub fn extract(self: *Read, entry: Entry, flags: c_int) !void {
123 var r = c.ARCHIVE_RETRY;
124 while (r == c.ARCHIVE_RETRY) {
125 r = c.archive_read_extract(self.raw, entry.raw, flags);
126 }
127
128 if (r == c.ARCHIVE_WARN) {
129 std.log.warn("archive_read_extract: {s}", .{c.archive_error_string(self.raw)});
130 } else if (r != c.ARCHIVE_OK) {
131 std.log.err("archive_read_extract: {s}", .{c.archive_error_string(self.raw)});
132 return error.LibArchiveError;
133 }
134 }
135};
diff --git a/libs/xdg/xdg.zig b/libs/xdg/xdg.zig
new file mode 100644
index 0000000..8466066
--- /dev/null
+++ b/libs/xdg/xdg.zig
@@ -0,0 +1,36 @@
1const std = @import("std");
2
3const Allocator = std.mem.Allocator;
4const Dir = std.fs.Dir;
5
6pub fn getDataHome(allocator: Allocator, app_name: []const u8) ![]u8 {
7 if (std.os.getenv("XDG_DATA_HOME")) |data_home| {
8 return std.fs.path.join(allocator, &.{ data_home, app_name });
9 }
10
11 if (std.os.getenv("HOME")) |home| {
12 return std.fs.path.join(allocator, &.{ home, ".local", "share", app_name });
13 }
14
15 return error.HomeNotFound;
16}
17
18pub fn getBinHome(allocator: Allocator) ![]u8 {
19 if (std.os.getenv("HOME")) |home| {
20 return std.fs.path.join(allocator, &.{ home, ".local", "bin" });
21 }
22
23 return error.HomeNotFound;
24}
25
26pub fn openDataHome(allocator: Allocator, app_name: []const u8) !Dir {
27 var data_home = try getDataHome(allocator, app_name);
28 defer allocator.free(data_home);
29 return try std.fs.cwd().makeOpenPath(data_home, .{});
30}
31
32pub fn openBinHome(allocator: Allocator) !Dir {
33 var bin_home = try getBinHome(allocator);
34 defer allocator.free(bin_home);
35 return try std.fs.cwd().makeOpenPath(bin_home, .{});
36}