From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id MN4sFYdPpmJTdAAAbAwnHQ (envelope-from ) for ; Sun, 12 Jun 2022 22:41:43 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id SOpZFIdPpmJHLAAAG6o9tA (envelope-from ) for ; Sun, 12 Jun 2022 22:41:43 +0200 Received: from mail.notmuchmail.org (yantan.tethera.net [135.181.149.255]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id D360612162 for ; Sun, 12 Jun 2022 22:41:42 +0200 (CEST) Received: from yantan.tethera.net (localhost [127.0.0.1]) by mail.notmuchmail.org (Postfix) with ESMTP id 6958A5F6B8; Sun, 12 Jun 2022 20:41:35 +0000 (UTC) Received: from fethera.tethera.net (fethera.tethera.net [IPv6:2607:5300:60:c5::1]) by mail.notmuchmail.org (Postfix) with ESMTP id 9D9B45F525 for ; Sun, 12 Jun 2022 20:41:30 +0000 (UTC) Received: by fethera.tethera.net (Postfix, from userid 1001) id DF9585FC11; Sun, 12 Jun 2022 16:41:29 -0400 (EDT) Received: (nullmailer pid 3806109 invoked by uid 1000); Sun, 12 Jun 2022 19:05:03 -0000 From: David Bremner To: notmuch@notmuchmail.org Subject: [PATCH 3/4] WIP: support show --duplicate for structured output Date: Sun, 12 Jun 2022 16:04:58 -0300 Message-Id: <20220612190459.3804908-4-david@tethera.net> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220612190459.3804908-1-david@tethera.net> References: <20220612190459.3804908-1-david@tethera.net> MIME-Version: 1.0 Message-ID-Hash: X3KTT7GZ53F563ULYR3CEH5JHNDCHJKQ X-Message-ID-Hash: X3KTT7GZ53F563ULYR3CEH5JHNDCHJKQ X-MailFrom: bremner@tethera.net X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-notmuch.notmuchmail.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.3 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: DE ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1655066502; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-owner:list-unsubscribe:list-subscribe:list-post; bh=Bs/0qxe0sLsDweGMjERDWaZidQeWmQe2OLgO39Tsv/8=; b=E22CIAMhB4ZKTuVtOsfOvOkTU/xxEgMNDFVzs5xfrwpdoBx2T3nHO8CBdF0DKLJmLaYy8e atfcDIfE+0CvzSD5cz2JeNI8ECEb18yekti8zBExZVZZ24FGP8IG5hSv/WrFSnar2N1WCo 1bYW20vhDLBnQlBpcsk3BhnNHopuQE392uf1fI+uAoBVgU7M6C+ed4l8sQUNonYv2vfeX+ Z72v6Wc+1zWONKH3b2iPBYsXRz6WJmJGPuAIfQydtl8eHBpE5dKa9Hhx6joOHov9Ywhqm/ tD1DiRkClvXPUmeqcfpKvYYDg3kIQGRw3JIk7IkW1+CoL8++kpYflABRwltxKg== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1655066502; a=rsa-sha256; cv=none; b=Txl70hmrWI/ZFZA/DE6eew71TqODm+l0u/6SDFGfGBFKGr9xGIstmFPRQtcg2LTOqCd+eU Ad/0CoNIQxmcwM3n1snEnwSMA8m5gsEYygM903Uf1ep89kAN7jXhgreil9mXvLZIThwyUW Dbbz765RQW8vSgwNkTuWxmO/2X3PrALLNVhK6Latb6KKOEg9hprJO6NVyrC9v+m3bT706f 48KhMHg17VZXZnL0DyBpoc4xgz0TD8deYd1lCwakq2Yy9UM5tKu1JGE0uIpgUm6ksk+y3J 5qu1OW866QDRwrdDDy69bhKo8OWawGZ1oM9DL+juashcEDIdh5FXC4AnoMHuXQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 135.181.149.255 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Migadu-Spam-Score: -1.11 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 135.181.149.255 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Migadu-Queue-Id: D360612162 X-Spam-Score: -1.11 X-Migadu-Scanner: scn1.migadu.com X-TUID: Mj4HbaE2iJEi --- mime-node.c | 32 +++++++++++++++++++++++--------- notmuch-client.h | 4 +++- notmuch-reply.c | 2 +- notmuch-show.c | 2 +- test/T520-show.sh | 24 ++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 12 deletions(-) diff --git a/mime-node.c b/mime-node.c index d29c4e48..890c8a0d 100644 --- a/mime-node.c +++ b/mime-node.c @@ -78,13 +78,14 @@ mime_node_get_message_crypto_status (mime_node_t *node) notmuch_status_t mime_node_open (const void *ctx, notmuch_message_t *message, + int duplicate, _notmuch_crypto_t *crypto, mime_node_t **root_out) { const char *filename = notmuch_message_get_filename (message); mime_node_context_t *mctx; mime_node_t *root; notmuch_status_t status; - int fd; + int fd = -1; root = talloc_zero (ctx, mime_node_t); if (root == NULL) { @@ -103,20 +104,33 @@ mime_node_open (const void *ctx, notmuch_message_t *message, talloc_set_destructor (mctx, _mime_node_context_free); /* Fast path */ - fd = open (filename, O_RDONLY); + if (duplicate <= 0) + fd = open (filename, O_RDONLY); if (fd == -1) { - /* Slow path - for some reason the first file in the list is - * not available anymore. This is clearly a problem in the + /* Slow path - Either we are trying to open a specific file, or + * for some reason the first file in the list is + * not available anymore. The latter is clearly a problem in the * database, but we are not going to let this problem be a * show stopper */ notmuch_filenames_t *filenames; + int i=1; + for (filenames = notmuch_message_get_filenames (message); notmuch_filenames_valid (filenames); - notmuch_filenames_move_to_next (filenames)) { - filename = notmuch_filenames_get (filenames); - fd = open (filename, O_RDONLY); - if (fd != -1) - break; + notmuch_filenames_move_to_next (filenames), i++) { + if (i>= duplicate) { + filename = notmuch_filenames_get (filenames); + fd = open (filename, O_RDONLY); + if (fd != -1) { + break; + } else { + if (duplicate > 0) { + fprintf (stderr, "Error opening %s: %s\n", filename, strerror (errno)); + status = NOTMUCH_STATUS_FILE_ERROR; + goto DONE; + } + } + } } talloc_free (filenames); diff --git a/notmuch-client.h b/notmuch-client.h index f8f987e7..faea52b7 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -389,7 +389,8 @@ struct mime_node { }; /* Construct a new MIME node pointing to the root message part of - * message. If crypto->verify is true, signed child parts will be + * message. Use the duplicate-th filename if that parameter is + * positive. If crypto->verify is true, signed child parts will be * verified. If crypto->decrypt is NOTMUCH_DECRYPT_TRUE, encrypted * child parts will be decrypted using either stored session keys or * asymmetric crypto. If crypto->decrypt is NOTMUCH_DECRYPT_AUTO, @@ -407,6 +408,7 @@ struct mime_node { */ notmuch_status_t mime_node_open (const void *ctx, notmuch_message_t *message, + int duplicate, _notmuch_crypto_t *crypto, mime_node_t **node_out); /* Return a new MIME node for the requested child part of parent. diff --git a/notmuch-reply.c b/notmuch-reply.c index 9fca22db..ee50bb22 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -663,7 +663,7 @@ do_reply (notmuch_database_t *notmuch, notmuch_messages_move_to_next (messages)) { message = notmuch_messages_get (messages); - if (mime_node_open (notmuch, message, ¶ms->crypto, &node)) + if (mime_node_open (notmuch, message, 0, ¶ms->crypto, &node)) return 1; reply = create_reply_message (notmuch, message, diff --git a/notmuch-show.c b/notmuch-show.c index 7b57aab3..ccaf9fa0 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1018,7 +1018,7 @@ show_message (void *ctx, session_key_count_error = notmuch_message_count_properties (message, "session-key", &session_keys); - status = mime_node_open (local, message, &(params->crypto), &root); + status = mime_node_open (local, message, params->duplicate, &(params->crypto), &root); if (status) goto DONE; part = mime_node_seek_dfs (root, (params->part < 0 ? 0 : params->part)); diff --git a/test/T520-show.sh b/test/T520-show.sh index 12bde6c7..a19b4d57 100755 --- a/test/T520-show.sh +++ b/test/T520-show.sh @@ -45,4 +45,28 @@ if [ $NOTMUCH_HAVE_SFSEXP -eq 1 ]; then fi +add_email_corpus duplicate + +ID1=debian/2.6.1.dfsg-4-1-g87ea161@87ea161e851dfb1ea324af00e4ecfccc18875e15 +test_begin_subtest "format json, subject, --duplicate=1" +output=$(notmuch show --format=json --duplicate=1 id:${ID1}) +file=$(notmuch search --output=files id:${ID1} | head -n 1) +subject=$(sed -n 's/^Subject: \(.*\)$/\1/p' < $file) +test_json_nodes <<<"$output" "subject:['headers']['Subject']=\"$subject\"" + +test_begin_subtest "format json, subject, --duplicate=2" +output=$(notmuch show --format=json --duplicate=2 id:${ID1}) +file=$(notmuch search --output=files id:${ID1} | tail -n 1) +subject=$(sed -n 's/^Subject: \(.*\)$/\1/p' < $file) +test_json_nodes <<<"$output" "subject:['headers']['Subject']=\"$subject\"" + +ID2=87r2geywh9.fsf@tethera.net +for dup in {1..2}; do + test_begin_subtest "format json, body, --duplicate=${dup}" + output=$(notmuch show --format=json --duplicate=${dup} id:${ID2} | \ + python $NOTMUCH_SRCDIR/test/json_check_nodes.py "body:['body'][0]['content']" | \ + grep '^# body') + test_expect_equal "$output" "# body ${dup}" +done + test_done -- 2.35.2