Commit Diff


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 <url>`, 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 <url>` 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 <ctype.h>
 #include <math.h>
 
+
 #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,