commit d3b38006cdb9ff7869f844c6b98f7c6073573df6 from: Oliver Lowe date: Sun Sep 7 08:37:32 2025 UTC Filter temp outgoing mail file using zig commit - cab59c0fbb25e07921a546b510782a3496c84ced commit + d3b38006cdb9ff7869f844c6b98f7c6073573df6 blob - 1eef23314842d0aa522f7fdcd0f9d640eba69644 blob + d91574e8e0019a70ac88025c8d8eef9578882639 --- src/build.zig +++ src/build.zig @@ -108,7 +108,6 @@ pub fn build(b: *std.Build) void { etpan.addIncludePath(b.path(".")); etpan.addIncludePath(b.path("common")); - // We will also create a module for our other entry point, 'main.zig'. const exe_mod = b.createModule(.{ .target = target, .optimize = optimize, @@ -135,7 +134,7 @@ pub fn build(b: *std.Build) void { "-DGTK_DISABLE_DEPRECATION_WARNINGS", "-DGDK_DISABLE_DEPRECATION_WARNINGS", "-g", - // "-std=c11", + "-std=c17", }, }); exe.addIncludePath(b.path("..")); blob - 68bb3dbebc8f0f17b8d6550cc24e1c2465f2634f (mode 644) blob + /dev/null --- src/fence/build.zig +++ /dev/null @@ -1,21 +0,0 @@ -const std = @import("std"); - -pub fn build(b: *std.Build) void { - const mod = b.createModule(.{ - .root_source_file = b.path("src/root.zig"), - .target = b.standardTargetOptions(.{}), - }); - - const lib = b.addLibrary(.{ - .linkage = .static, - .name = "fence", - .root_module = mod, - }); - // https://github.com/ziglang/zig/issues/6817 - lib.bundle_compiler_rt = true; - - b.installArtifact(lib); - - const header_file = b.addInstallHeaderFile(b.path("src/fence.h"), "fence.h"); - b.getInstallStep().dependOn(&header_file.step); -} blob - 27533b9f35d63c62a30812e20109692d7d52b33e (mode 644) blob + /dev/null --- src/fence/build.zig.zon +++ /dev/null @@ -1,86 +0,0 @@ -.{ - // This is the default name used by packages depending on this one. For - // example, when a user runs `zig fetch --save `, this field is used - // as the key in the `dependencies` table. Although the user can choose a - // different name, most users will stick with this provided value. - // - // It is redundant to include "zig" in this name because it is already - // within the Zig package namespace. - .name = .chestertons_fence, - - // This is a [Semantic Version](https://semver.org/). - // In a future version of Zig it will be used for package deduplication. - .version = "0.0.0", - - // Together with name, this represents a globally unique package - // identifier. This field is generated by the Zig toolchain when the - // package is first created, and then *never changes*. This allows - // unambiguous detection of one package being an updated version of - // another. - // - // When forking a Zig project, this id should be regenerated (delete the - // field and run `zig build`) if the upstream project is still maintained. - // Otherwise, the fork is *hostile*, attempting to take control over the - // original project's identity. Thus it is recommended to leave the comment - // on the following line intact, so that it shows up in code reviews that - // modify the field. - .fingerprint = 0x9a0d03fed7adc588, // Changing this has security and trust implications. - - // Tracks the earliest Zig version that the package considers to be a - // supported use case. - .minimum_zig_version = "0.14.0+5ad91a646", - - // This field is optional. - // Each dependency must either provide a `url` and `hash`, or a `path`. - // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. - // Once all dependencies are fetched, `zig build` no longer requires - // internet connectivity. - .dependencies = .{ - // See `zig fetch --save ` for a command-line interface for adding dependencies. - //.example = .{ - // // When updating this field to a new URL, be sure to delete the corresponding - // // `hash`, otherwise you are communicating that you expect to find the old hash at - // // the new URL. If the contents of a URL change this will result in a hash mismatch - // // which will prevent zig from using it. - // .url = "https://example.com/foo.tar.gz", - // - // // This is computed from the file contents of the directory of files that is - // // obtained after fetching `url` and applying the inclusion rules given by - // // `paths`. - // // - // // This field is the source of truth; packages do not come from a `url`; they - // // come from a `hash`. `url` is just one of many possible mirrors for how to - // // obtain a package matching this `hash`. - // // - // // Uses the [multihash](https://multiformats.io/multihash/) format. - // .hash = "...", - // - // // When this is provided, the package is found in a directory relative to the - // // build root. In this case the package's hash is irrelevant and therefore not - // // computed. This field and `url` are mutually exclusive. - // .path = "foo", - // - // // When this is set to `true`, a package is declared to be lazily - // // fetched. This makes the dependency only get fetched if it is - // // actually used. - // .lazy = false, - //}, - }, - - // Specifies the set of files and directories that are included in this package. - // Only files and directories listed here are included in the `hash` that - // is computed for this package. Only files listed here will remain on disk - // when using the zig package manager. As a rule of thumb, one should list - // files required for compilation plus any license(s). - // Paths are relative to the build root. Use the empty string (`""`) to refer to - // the build root itself. - // A directory listed here means that all files within, recursively, are included. - .paths = .{ - "build.zig", - "build.zig.zon", - "src", - // For example... - //"LICENSE", - //"README.md", - }, -} blob - 8ed50fe25e21cce9ceb3ffa3225a288571cb5390 blob + 90683e5ab7dcdb5e61181c4bed770396903c0058 --- src/fence/src/fence.h +++ src/fence/src/fence.h @@ -1,2 +1,3 @@ char fence_is_top_level_domain(char *domain); int quote_depth(char *line); +size_t fence_copy_after_line(char *dst, char *src, char *line); blob - 2092b5b9e7ff5f37e9c1d1eb62d2140c0519bbf1 blob + 3db3c90ce76ac72f363922645c8e805460932a7c --- src/fence/src/root.zig +++ src/fence/src/root.zig @@ -29,7 +29,7 @@ fn quoteDepth(line: []const u8) u8 { var depth: u8 = 0; const last = std.mem.lastIndexOfScalar(u8, ln, '>') orelse return 1; - for (line[first..last+1]) |c| { + for (line[first .. last + 1]) |c| { if (c == '>') { if (depth == 0xff) return depth; depth += 1; @@ -46,16 +46,45 @@ export fn quote_depth(line: [*:0]const u8) c_int { return @as(c_int, n); } +fn copyAfterLine(dst: std.fs.File, src: std.fs.File, key: []const u8) !usize { + var buf: [8192]u8 = undefined; + var rd = std.io.bufferedReader(src.reader()); + var r = rd.reader(); + var wr = std.io.bufferedWriter(dst.writer()); + var w = wr.writer(); + var found = false; + var n: usize = 0; + while (try r.readUntilDelimiterOrEof(buf[0..], '\n')) |line| { + if (std.mem.startsWith(u8, line, key)) { + found = true; + continue; + } + if (!found) continue; + try w.print("{s}\n", .{line}); + n += (line.len + 1); // + 1 for newline + } + try wr.flush(); + return n; +} + +export fn fence_copy_after_line(dst: [*:0]const u8, src: [*:0]const u8, line: [*:0]const u8) usize { + const fdst = std.fs.cwd().createFile(std.mem.span(dst), .{}) catch return 0; + defer fdst.close(); + const fsrc = std.fs.cwd().openFile(std.mem.span(src), .{}) catch return 0; + defer fsrc.close(); + return copyAfterLine(fdst, fsrc, std.mem.span(line)) catch 0; +} + test "quote depth" { - const tests = [_]struct{[]const u8, u8}{ - .{">>> hello", 3}, - .{"> >> hello", 3}, - .{" > hello >", 1}, - .{"hello>>", 0}, - .{">> hello >>", 2}, - .{"> \t> hello", 2}, - .{">", 1}, - .{ "xxx > hello >>", 0}, + const tests = [_]struct { []const u8, u8 }{ + .{ ">>> hello", 3 }, + .{ "> >> hello", 3 }, + .{ " > hello >", 1 }, + .{ "hello>>", 0 }, + .{ ">> hello >>", 2 }, + .{ "> \t> hello", 2 }, + .{ ">", 1 }, + .{ "xxx > hello >>", 0 }, }; for (tests) |t| { const got = quoteDepth(t[0]); blob - 40c2e3a1f5d476eb3aec3ff79a140b896d1282f3 blob + 6694f52e5acbb40e8cb333f5eeaef4c33797c063 --- src/procmime.c +++ src/procmime.c @@ -32,7 +32,6 @@ #include "procmime.h" #include "procheader.h" #include "quoted-printable.h" -#include "uuencode.h" #include "unmime.h" #include "html.h" #include "codeconv.h" @@ -426,26 +425,6 @@ gboolean procmime_decode_content(MimeInfo *mimeinfo) if (tmpfp != outfp) { fclose(tmpfp); } - } else if (encoding == ENC_X_UUENCODE) { - gchar outbuf[BUFFSIZE]; - glong len; - gboolean flag = FALSE; - - while ((ftell(infp) < readend) && (fgets(buf, sizeof(buf), infp) != NULL)) { - if (!flag && strncmp(buf,"begin ", 6)) continue; - - if (flag) { - len = fromuutobits(outbuf, buf); - if (len <= 0) { - if (len < 0) - g_warning("bad UUENCODE content (%ld)", len); - break; - } - if (fwrite(outbuf, sizeof(gchar), (size_t)len, outfp) < (size_t)len) - err = TRUE; - } else - flag = TRUE; - } } else { while ((ftell(infp) < readend) && (fgets(buf, sizeof(buf), infp) != NULL)) { if (!flowed) { blob - 548b88c1b3a75a68a05e113242d9385021083b99 blob + 40cb0d741828c3de2c95021b26669e0743ee0c05 --- src/procmsg.c +++ src/procmsg.c @@ -26,6 +26,7 @@ #include #include + #include "main.h" #include "utils.h" #include "procmsg.h" @@ -33,6 +34,7 @@ #include "send_message.h" #include "procmime.h" #include "statusbar.h" +#include "fence.h" #include "folder.h" #include "foldersel.h" #include "prefs_common.h" @@ -949,51 +951,6 @@ gboolean procmsg_queue_is_empty(FolderItem *queue) return res; } -gint procmsg_remove_special_headers(const gchar *in, const gchar *out) -{ - FILE *fp, *outfp; - gchar buf[BUFFSIZE]; - - if ((fp = g_fopen(in, "rb")) == NULL) { - FILE_OP_ERROR(in, "g_fopen"); - return -1; - } - if ((outfp = g_fopen(out, "wb")) == NULL) { - FILE_OP_ERROR(out, "g_fopen"); - fclose(fp); - return -1; - } - while (fgets(buf, sizeof(buf), fp) != NULL) { - /* new way */ - if ((!strncmp(buf, "X-Claws-End-Special-Headers: 1", - strlen("X-Claws-End-Special-Headers:"))) || - (!strncmp(buf, "X-Sylpheed-End-Special-Headers: 1", - strlen("X-Sylpheed-End-Special-Headers:")))) - break; - /* old way */ - if (buf[0] == '\r' || buf[0] == '\n') break; - /* from other mailers */ - if (!strncmp(buf, "Date: ", 6) - || !strncmp(buf, "To: ", 4) - || !strncmp(buf, "From: ", 6) - || !strncmp(buf, "Subject: ", 9)) { - rewind(fp); - break; - } - } - while (fgets(buf, sizeof(buf), fp) != NULL) { - if (fputs(buf, outfp) == EOF) { - FILE_OP_ERROR(out, "fputs"); - fclose(outfp); - fclose(fp); - return -1; - } - } - safe_fclose(outfp); - fclose(fp); - return 0; -} - gint procmsg_save_to_outbox(FolderItem *outbox, const gchar *file) { gint num; @@ -1017,7 +974,8 @@ gint procmsg_save_to_outbox(FolderItem *outbox, const g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg.out.%08x", get_rc_dir(), G_DIR_SEPARATOR, (guint) rand()); - if (procmsg_remove_special_headers(file, tmp) !=0) + char *end = "X-Claws-End-Special-Headers:"; + if (fence_copy_after_line(tmp, file, end) == 0) return -1; while (folder_item_scan(outbox) < 0) { blob - cef01078d451ca1e6cc77a5c33ebf193b403cf41 blob + dcb5581070469d1c90b24ac2a162bf6bfdaa6d09 --- src/procmsg.h +++ src/procmsg.h @@ -346,8 +346,6 @@ void procmsg_msginfo_change_flags (MsgInfo *msginfo, MsgTmpFlags add_tmp_flags, MsgPermFlags rem_perm_flags, MsgTmpFlags rem_tmp_flags); -gint procmsg_remove_special_headers (const gchar *in, - const gchar *out); gint procmsg_save_to_outbox(FolderItem *outbox, const gchar *file); gboolean procmsg_msg_has_flagged_parent (MsgInfo *info,