Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 10C0C431FD5 for ; Sat, 26 Jul 2014 20:53:13 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -2.3 X-Spam-Level: X-Spam-Status: No, score=-2.3 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_MED=-2.3] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CEJ4n+PJjDqO for ; Sat, 26 Jul 2014 20:53:05 -0700 (PDT) Received: from dmz-mailsec-scanner-4.mit.edu (dmz-mailsec-scanner-4.mit.edu [18.9.25.15]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by olra.theworths.org (Postfix) with ESMTPS id 7454C431FB6 for ; Sat, 26 Jul 2014 20:53:05 -0700 (PDT) X-AuditID: 1209190f-f79f86d0000061c8-dd-53d4779fc9a2 Received: from mailhub-auth-3.mit.edu ( [18.9.21.43]) (using TLS with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by dmz-mailsec-scanner-4.mit.edu (Symantec Messaging Gateway) with SMTP id 6E.91.25032.F9774D35; Sat, 26 Jul 2014 23:53:03 -0400 (EDT) Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id s6R3r2BV004148; Sat, 26 Jul 2014 23:53:02 -0400 Received: from drake.dyndns.org (216-15-114-40.c3-0.arl-ubr1.sbo-arl.ma.cable.rcn.com [216.15.114.40]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id s6R3r012016412 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Sat, 26 Jul 2014 23:53:01 -0400 Received: from amthrax by drake.dyndns.org with local (Exim 4.77) (envelope-from ) id 1XBFW8-00051h-HJ; Sat, 26 Jul 2014 23:53:00 -0400 From: Austin Clements To: notmuch@notmuchmail.org Subject: [PATCH 13/14] lib: Return an error from operations that require an upgrade Date: Sat, 26 Jul 2014 23:52:52 -0400 Message-Id: <1406433173-19169-14-git-send-email-amdragon@mit.edu> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1406433173-19169-1-git-send-email-amdragon@mit.edu> References: <1406433173-19169-1-git-send-email-amdragon@mit.edu> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrIIsWRmVeSWpSXmKPExsUixCmqrTu//EqwwfMFKhbXb85kdmD0eLbq FnMAYxSXTUpqTmZZapG+XQJXxp7uXvaCG9oVZxpnszUwNqt0MXJwSAiYSCz4b9PFyAlkiklc uLeerYuRi0NIYDaTxJ9rHxghnI2MEq8+rWWFcO4wSTz48o4ZwpnLKPH0wzk2kH42AQ2JbfuX M4LYIgLSEjvvzmYFWcEsoCbxp0sFJCwsECwx++IfVhCbRUBV4sjbY0wgNq+Ao8TnmQdZIc6Q k2i48QlsJCdQ/PizE2wgY4QEHCRuXUqcwMi/gJFhFaNsSm6Vbm5iZk5xarJucXJiXl5qka6J Xm5miV5qSukmRnDISPLvYPx2UOkQowAHoxIPbwbblWAh1sSy4srcQ4ySHExKorz7zYBCfEn5 KZUZicUZ8UWlOanFhxglOJiVRHiFioFyvCmJlVWpRfkwKWkOFiVx3rfWVsFCAumJJanZqakF qUUwWRkODiUJ3htlQI2CRanpqRVpmTklCGkmDk6Q4TxAwzeUggwvLkjMLc5Mh8ifYlSUEuf9 BZIQAElklObB9cJi+hWjONArwrysICt4gOkArvsV0GAmoMEs/pdBBpckIqSkGhhZDl+ddKBZ /vqhNdOzlmRKcyz3ux6wOT+wrNLo9orlbzmvcf2ubnyQ90tgZunKKO/KXepKL+b6HzVd88qS bUHCgqgV/gmVgUellF0cJyk1CyhvzWCPsFDIOBoQ1aw96Q9PUptIO+9HBRetXdeCfTi3fzFS ztlZo1StbXyF54PLjmrbHe8nX1NiKc5INNRiLipOBADn3u6ZxAIAAA== X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Jul 2014 03:53:13 -0000 Previously, there was no protection against a caller invoking an operation on an old database version that would effectively corrupt the database by treating it like a newer version. According to notmuch.h, any caller that opens the database in read/write mode is supposed to check if the database needs upgrading and perform an upgrade if it does. This would protect against this, but nobody (even the CLI) actually does this. However, with features, it's easy to protect against incompatible operations on a fine-grained basis. This lightweight change allows callers to safely operate on old database versions, while preventing specific operations that would corrupt the database with an informative error message. --- lib/database.cc | 5 +++++ lib/directory.cc | 5 +++++ lib/message.cc | 8 ++++++++ lib/notmuch.h | 16 ++++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/lib/database.cc b/lib/database.cc index a93281c..f105e27 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -311,6 +311,8 @@ notmuch_status_to_string (notmuch_status_t status) return "Unbalanced number of calls to notmuch_database_begin_atomic/end_atomic"; case NOTMUCH_STATUS_UNSUPPORTED_OPERATION: return "Unsupported operation"; + case NOTMUCH_STATUS_UPGRADE_REQUIRED: + return "Operation requires a database upgrade"; default: case NOTMUCH_STATUS_LAST_STATUS: return "Unknown error status value"; @@ -2223,6 +2225,9 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch, if (message_ret == NULL) return NOTMUCH_STATUS_NULL_POINTER; + if (! (notmuch->features & NOTMUCH_FEATURE_FILE_TERMS)) + return NOTMUCH_STATUS_UPGRADE_REQUIRED; + /* return NULL on any failure */ *message_ret = NULL; diff --git a/lib/directory.cc b/lib/directory.cc index 6a3ffed..8daaec8 100644 --- a/lib/directory.cc +++ b/lib/directory.cc @@ -105,6 +105,11 @@ _notmuch_directory_create (notmuch_database_t *notmuch, const char *db_path; notmuch_bool_t create = (flags & NOTMUCH_FIND_CREATE); + if (! (notmuch->features & NOTMUCH_FEATURE_DIRECTORY_DOCS)) { + *status_ret = NOTMUCH_STATUS_UPGRADE_REQUIRED; + return NULL; + } + *status_ret = NOTMUCH_STATUS_SUCCESS; path = _notmuch_database_relative_path (notmuch, path); diff --git a/lib/message.cc b/lib/message.cc index 4fc427f..1618e81 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -653,6 +653,10 @@ _notmuch_message_add_filename (notmuch_message_t *message, if (filename == NULL) INTERNAL_ERROR ("Message filename cannot be NULL."); + if (! (message->notmuch->features & NOTMUCH_FEATURE_FILE_TERMS) || + ! (message->notmuch->features & NOTMUCH_FEATURE_BOOL_FOLDER)) + return NOTMUCH_STATUS_UPGRADE_REQUIRED; + relative = _notmuch_database_relative_path (message->notmuch, filename); status = _notmuch_database_split_path (local, relative, &directory, NULL); @@ -697,6 +701,10 @@ _notmuch_message_remove_filename (notmuch_message_t *message, notmuch_private_status_t private_status; notmuch_status_t status; + if (! (message->notmuch->features & NOTMUCH_FEATURE_FILE_TERMS) || + ! (message->notmuch->features & NOTMUCH_FEATURE_BOOL_FOLDER)) + return NOTMUCH_STATUS_UPGRADE_REQUIRED; + status = _notmuch_database_filename_to_direntry ( local, message->notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry); if (status || !direntry) diff --git a/lib/notmuch.h b/lib/notmuch.h index 3c5ec98..cbf2ba5 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -160,6 +160,10 @@ typedef enum _notmuch_status { */ NOTMUCH_STATUS_UNSUPPORTED_OPERATION, /** + * The operation requires a database upgrade. + */ + NOTMUCH_STATUS_UPGRADE_REQUIRED, + /** * Not an actual status value. Just a way to find out how many * valid status values there are. */ @@ -438,6 +442,9 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch); * * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred; * directory not retrieved. + * + * NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the + * database to use this function. */ notmuch_status_t notmuch_database_get_directory (notmuch_database_t *database, @@ -490,6 +497,9 @@ notmuch_database_get_directory (notmuch_database_t *database, * * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only * mode so no message can be added. + * + * NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the + * database to use this function. */ notmuch_status_t notmuch_database_add_message (notmuch_database_t *database, @@ -520,6 +530,9 @@ notmuch_database_add_message (notmuch_database_t *database, * * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only * mode so no message can be removed. + * + * NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the + * database to use this function. */ notmuch_status_t notmuch_database_remove_message (notmuch_database_t *database, @@ -575,6 +588,9 @@ notmuch_database_find_message (notmuch_database_t *database, * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating the message object * * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred + * + * NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the + * database to use this function. */ notmuch_status_t notmuch_database_find_message_by_filename (notmuch_database_t *notmuch, -- 2.0.0