Commit graph

114 commits

Author SHA1 Message Date
Jani Nikula
65ebd34329 cli: only check the ignore list if needed
Premature optimization is the root of all evil, but this is simple
enough.
2014-01-26 09:37:01 -04:00
Jani Nikula
caf5514a36 cli: extract single message addition in notmuch new to clarify code
The add_files() function has grown huge, chop it up a bit. No
functional changes.
2014-01-26 09:36:51 -04:00
Jani Nikula
c745377306 cli: clean up exit status code returned by the cli commands
Apart from the status codes for format mismatches, the non-zero exit
status codes have been arbitrary. Make the cli consistently return
either EXIT_SUCCESS or EXIT_FAILURE.
2014-01-18 14:45:26 -04:00
Austin Clements
516efb7807 new: Don't scan unchanged directories with no sub-directories
This can substantially reduce the cost of notmuch new in some
situations, such as when the file system cache is cold or when the
Maildir is on NFS.
2013-10-28 16:47:10 -03:00
Jani Nikula
4ef2106792 cli: move config open/close to main() from subcommands
This allows specifying config file as a top level argument to notmuch,
and generally makes it possible to override config file options in
main(), without having to touch the subcommands.

If the config file does not exist, one will be created for the notmuch
main command and setup and help subcommands. Help is special in this
regard; the config is created just to avoid errors about missing
config, but it will not be saved.

This also makes notmuch config the talloc context for subcommands.
2013-03-08 07:54:41 -04:00
Jani Nikula
e76f6517de cli: config: make notmuch_config_open() "is new" parameter input only
We now have a notmuch_config_is_new() function to query whether a
config was created or not. Change the notmuch_config_open() is_new
parameter into boolean create_new to determine whether the function
should create a new config if one doesn't exist. This reduces the
complexity of the API.
2013-03-07 09:39:12 -04:00
Jani Nikula
11365abb90 cli: convert "notmuch new" to the argument parser
Use the notmuch argument parser to handle arguments in "notmuch
new". As a side effect, this fixes broken STRNCMP_LITERAL usage that
accepts, for example, --verbosefoo for --verbose.
2012-12-04 09:10:33 -04:00
Austin Clements
7611a72be2 new: Skip ignored broken symlinks
We now test for user ignore patterns before attempting to determine if
a directory entry is itself a directory.  As a result, we no longer
abort for broken symlinks if the user has explicitly ignored them.

This fixes the test added in the previous patch.  It also slightly
changes the debug output checked by another test of ignores.
2012-11-26 22:17:20 -04:00
Pieter Praet
97216b3cb8 cli: notmuch new: optionally output debug information when ignoring files/directories
When running 'notmuch new' with the '--debug' option, output debug
information regarding explicitly ignored files and directories.
2012-10-20 17:28:19 -03:00
Pieter Praet
12d328a597 cli: add '--debug' option to 'notmuch new'
This will be used in later patches to test the 'new.ignore'
config option more thoroughly.
2012-10-20 17:27:58 -03:00
Austin Clements
4ca36441a8 new: Unify add_files and add_files_recursive
Since starting at the top of a directory tree and recursing within
that tree are now identical operations, there's no need for both
add_files and add_files_recursive.  This eliminates add_files (which
did nothing more than call add_files_recursive after the previous
patch) and renames add_files_recursive to add_files.
2012-05-24 21:53:38 -03:00
Austin Clements
da170ee657 new: Merge error checks from add_files and add_files_recursive
Previously, add_files_recursive could have been called on a symlink to
a non-directory.  Hence, calling it on a non-directory was not an
error, so a separate function, add_files, existed to fail loudly in
situations where the path had to be a directory.

With the new stat-ing logic, add_files_recursive is always called on
directories, so the separation of this logic is no longer necessary.
Hence, this patch moves the strict error checking previously done by
add_files into add_files_recursive.
2012-05-24 21:53:19 -03:00
Austin Clements
d99270c450 new: Centralize file type stat-ing logic
This moves our logic to get a file's type into one function.  This has
several benefits: we can support OSes and file systems that do not
provide dirent.d_type or always return DT_UNKNOWN, complex
symlink-handling logic has been replaced by a simple stat fall-through
in one place, and the error message for un-stat-able file is more
accurate (previously, the error always mentioned directories, even
though a broken symlink is not a directory).
2012-05-24 21:53:08 -03:00
Austin Clements
3f3c446c40 new: Remove workaround for detecting newly created directory objects
Previously, notmuch_database_get_directory did not indicate whether or
not the returned directory object was newly created, which required a
workaround to distinguish newly created directory objects with no
child messages from directory objects that had no mtime set but did
have child messages.  Now that notmuch_database_get_directory
distinguishes whether or not the directory object exists in the
database, this workaround is no longer necessary.
2012-05-23 22:31:10 -03:00
Austin Clements
7199d22f43 lib/cli: Make notmuch_database_get_directory return a status code
Previously, notmuch_database_get_directory had no way to indicate how
it had failed.  This changes its prototype to return a status code and
set an out-argument to the retrieved directory, like similar functions
in the library API.  This does *not* change its currently broken
behavior of creating directory objects when they don't exist, but it
does document it and paves the way for fixing this.  Also, it can now
check for a read-only database and return
NOTMUCH_STATUS_READ_ONLY_DATABASE instead of crashing.

In the interest of atomicity, this also updates calls from the CLI so
that notmuch still compiles.
2012-05-15 08:56:33 -03:00
Austin Clements
ba57294218 lib/cli: Make notmuch_database_create return a status code
This is the notmuch_database_create equivalent of the previous change.

In this case, there were places where errors were not being propagated
correctly in notmuch_database_create or in calls to it.  These have
been fixed, using the new status value.
2012-05-05 10:12:26 -03:00
Austin Clements
5fddc07dc3 lib/cli: Make notmuch_database_open return a status code
It has been a long-standing issue that notmuch_database_open doesn't
return any indication of why it failed.  This patch changes its
prototype to return a notmuch_status_t and set an out-argument to the
database itself, like other functions that return both a status and an
object.

In the interest of atomicity, this also updates every use in the CLI
so that notmuch still compiles.  Since this patch does not update the
bindings, the Python bindings test fails.
2012-05-05 10:11:57 -03:00
Justus Winter
6f7469f547 Use notmuch_database_destroy instead of notmuch_database_close
Adapt the notmuch binaries source to the notmuch_database_close split.

Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
2012-04-28 09:27:33 -03:00
Austin Clements
2e7b649404 new: Fix missing end_atomic in remove_filename on error
Previously, if we failed to find the message by filename in
remove_filename, we would return immediately from the function without
ending its atomic block.  Now this code follows the usual goto DONE
idiom to perform cleanup.
2012-04-24 23:25:52 -03:00
Austin Clements
746fef0aea new: Print final fatal error message to stderr
This was going to stdout.  I removed the newline at the beginning of
printing the fatal error message because it wouldn't make sense if you
were only looking at the stderr stream (e.g., you had redirected
stdout to /dev/null).
2012-04-24 23:25:52 -03:00
Austin Clements
d3b5533123 new: Handle fatal errors in remove_filename and _remove_directory
Previously such errors were simply ignored.  Now they cause an
immediate cleanup and abort.
2012-04-24 23:25:51 -03:00
Austin Clements
e075ee37c9 new: Consistently treat fatal errors as fatal
Previously, fatal errors in add_files_recursive were not treated as
fatal by its callers (including itself!).  This makes
add_files_recursive errors consistently fatal and updates all callers
to treat them as fatal.
2012-04-24 23:25:51 -03:00
Tomi Ollila
ce1e720de6 add support for user-specified files & directories to ignore
A new configuration key 'new.ignore' is used to determine which
files and directories user wants not to be scanned as new mails.

Mark the corresponding test as no longer broken.
This work merges my previous attempts and Andreas Amann's work
in id:"ylp7hi23mw8.fsf@tyndall.ie"
2012-02-17 08:04:34 -04:00
Ethan Glasser-Camp
5f39979a4a Free the results of scandir()
scandir() returns "strings allocated via malloc(3)" which are then
"collected in array namelist which is allocated via
malloc(3)". Currently we just free the array namelist. Instead, free
all the entries of namelist, and then free namelist.

entry only points to elements of namelist, so we don't free it
separately.
2012-02-14 23:44:30 -04:00
Austin Clements
a9a9e374e2 Silence buildbot warnings about unused results
This ignores the results of the two writes in sigint handlers even
harder than before.

While my libc lacks the declarations that trigger these warnings, this
can be tested by adding the following to notmuch.h:

__attribute__((warn_unused_result))
ssize_t write(int fd, const void *buf, size_t count);
2012-01-21 08:49:50 -04:00
David Edmondson
77ec8108a1 notmuch: Quiet buildbot warnings.
Cast away the result of various *write functions. Provide a default
value for some variables to avoid "use before set" warnings.
2011-12-21 07:32:16 -04:00
Jani Nikula
69bb7f35b6 cli: add support for pre and post notmuch new hooks
Run notmuch new pre and post hooks, named "pre-new" and "post-new", if
present in the notmuch hooks directory. The hooks will be run before and
after incorporating new messages to the database.

Typical use cases for pre-new and post-new hooks are fetching or delivering
new mail to the maildir, and custom tagging of the mail incorporated to the
database.

Also add command line option --no-hooks to notmuch new to bypass the hooks.

Signed-off-by: Jani Nikula <jani@nikula.org>
2011-12-11 13:58:15 -04:00
David Bremner
61f0a5b8ee cli: change argument parsing convention for subcommands
previously we deleted the subcommand name from argv before passing to
the subcommand. In this version, the deletion is done in the actual
subcommands. Although this causes some duplication of code, it allows
us to be more flexible about how we parse command line arguments in
the subcommand, including possibly using off-the-shelf routines like
getopt_long that expect the name of the command in argv[0].
2011-10-22 19:42:54 -03:00
Ali Polatel
02a3076711 lib: make find_message{,by_filename) report errors
Previously, the functions notmuch_database_find_message() and
notmuch_database_find_message_by_filename() functions did not properly
report error condition to the library user.

For more information, read the thread on the notmuch mailing list
starting with my mail "id:871uv2unfd.fsf@gmail.com"

Make these functions accept a pointer to 'notmuch_message_t' as argument
and return notmuch_status_t which may be used to check for any error
condition.

restore: Modify for the new notmuch_database_find_message()
new: Modify for the new notmuch_database_find_message_by_filename()
2011-10-04 07:55:29 +03:00
Austin Clements
bff30540d8 new: Wrap adding and removing messages in atomic sections.
This addresses atomicity of tag synchronization, the last atomicity
problems in notmuch new.  Each message add or remove is wrapped in its
own atomic section, so interrupting notmuch new doesn't lose progress.
2011-09-24 20:00:29 -03:00
Austin Clements
8305f0aac7 new: Synchronize maildir flags eagerly.
Because flag synchronization is stateless, it can be performed at any
time as long as it's guaranteed to be performed after any change to a
message's filename list.  Take advantage of this to synchronize tags
immediately after a filename is added or removed.

This does not yet make adding or removing a message atomic, but it is
a big step toward atomicity because it reduces the window where the
database tags are inconsistent from nearly the entire notmuch-new to
just around when the message is added or removed.
2011-09-24 20:00:28 -03:00
Austin Clements
191c4ae693 new: Cleanup. De-duplicate file name removal code.
Previously, file name removal was implemented identically in two
places.  Now it's captured in one function.

This is important because file name removal is about to get slightly
more complicated with eager tag synchronization and correct removal
atomicity.
2011-09-24 20:00:28 -03:00
Austin Clements
1353dbe864 new: Cleanup. Put removed/renamed message count in add_files_state_t.
Previously, pointers to these variables were passed around
individually.  This was okay when only one function needed them, but
we're about to need them in a few more places.
2011-09-24 20:00:28 -03:00
Austin Clements
e59cc0031f lib: Add support for nested atomic sections.
notmuch_database_t now keeps a nesting count and we only start a
transaction or commit for the outermost atomic section.

Introduces a new error, NOTMUCH_STATUS_UNBALANCED_ATOMIC.
2011-09-23 21:50:38 -04:00
Austin Clements
fcd433709e new: Defer updating directory mtimes until the end.
Previously, if notmuch new were interrupted between updating the
directory mtime and handling removals from that directory, a
subsequent notmuch new would not handle those removals until something
else changed in that directory.  This defers recording the updated
mtime until after removals are handled to eliminate this problem.
2011-09-23 21:50:38 -04:00
Austin Clements
bdaee77e1b new: Don't lose messages on SIGINT.
Previously, message removals were always performed, even after a
SIGINT.  As a result, when a message was moved from one folder to
another, a SIGINT between processing the directory the message was
removed from and processing the directory it was added to would result
in notmuch removing that message from the database.
2011-09-13 22:00:15 -03:00
Austin Clements
bb2b33fbb8 new: Improved workaround for mistaken new directories
Currently, notmuch new assumes any directory with a database mtime of
0 is new, but we don't set the mtime until after processing messages
and subdirectories in that directory.  Hence, anything that prevents
the mtime update (such as an interruption or the wall-clock logic
introduced in 8c39e8d6) will cause the next notmuch new to think the
directory is still new.

We work around this by setting the new directory's database mtime to
-1 before scanning anything in the new directory.  This also obviates
the need for the workaround used in 8c39e8d6.
2011-06-29 16:10:41 -07:00
Austin Clements
8c39e8d6fb new: Don't update DB mtime if FS mtime equals wall-clock time.
This fixes a race where multiple message deliveries in the same second
with an intervening notmuch new could result in messages being ignored
by notmuch (at least, until a later delivery forced a rescan).
Because mtimes only have second granularity, later deliveries in the
same second won't change the directory mtime, and hence won't trigger
notmuch new to rescan the directory.  This situation can only occur
when notmuch new is being run at the same second as the directory's
modification time, so simply don't update the saved mtime in this
case.

This very race happens all over the test suite, and is currently
compensated for with increment_mtime (and, occasionally, luck).  With
this change, increment_mtime becomes unnecessary.
2011-06-29 15:26:04 -07:00
Pieter Praet
8bb6f7869c fix sum moar typos [comments in source code]
Various typo fixes in comments within the source code.

Signed-off-by: Pieter Praet <pieter@praet.org>

Edited-by: Carl Worth <cworth@cworth.org> Restricted to just
source-code comments, (and fixed fix of "descriptios" to "descriptors"
rather than "descriptions").
2011-06-23 15:58:39 -07:00
Carl Worth
2f3a76c569 Remove some variables which were set but not used.
gcc (at least as of version 4.6.0) is kind enough to point these out to us,
(when given -Wunused-but-set-variable explicitly or implicitly via -Wunused
or -Wall).

One of these cases was a legitimately unused variable. Two were simply
variables (named ignored) we were assigning only to squelch a warning about
unused function return values. I don't seem to be getting those warnings
even without setting the ignored variable. And the gcc docs. say that the
correct way to squelch that warning is with a cast to (void) anyway.
2011-05-11 13:27:14 -07:00
Carl Worth
61d4d89572 new: Update comments for add_files_recursive
The most recent commit optimized the implementation of this
function. This commit simply updates the relevant comments to match
the new implementation.
2011-03-10 11:56:16 -08:00
Karel Zak
b0006b6ea2 new: read db_files and db_subdirs only if mtime changed
The db_files and db_subdirs are unnecessary for unchanged directories.

maildir with 10000 e-mails:

old version:
	$ time ./notmuch new
	No new mail.

	real    0m0.053s
	user    0m0.028s
	sys     0m0.026s

new version:
	$ time ./notmuch new
	No new mail.

	real    0m0.032s
	user    0m0.009s
	sys     0m0.023s

Signed-off-by: Karel Zak <kzak@redhat.com>

Reviewed-by:  Austin Clements <amdragon@mit.edu>

Looks good (faster than, but provably equivalent to the original code!
notmuch_directory_get_child_* are side-effect free,
db_files/db_subdirs aren't used between where they were set in the old
code and where they are set in the new code, and db_files/db_subdirs
are initialized to NULL when declared).

Another timing data point:
Old code: ./notmuch new  0.77s user 0.28s system 99% cpu 1.051 total
New code: ./notmuch new  0.09s user 0.27s system 98% cpu 0.368 total
2011-03-10 11:48:33 -08:00
Michal Sojka
c58523088a new: Print progress estimates only when we have sufficient information
Without this patch, it might happen that the remaining time or processing
rate were calculated just after start where nothing was processed yet.
This resulted into division by a very small number (or zero) and the
printed information was of little value.

Instead of printing nonsenses we print only that the operation is in
progress. The estimates will be printed later, after there is enough data.
2011-01-26 23:47:51 +10:00
Michal Sojka
90a505373e new: Enhance progress reporting
notmuch new reports progress only during the "first" phase when the
files on disk are traversed and indexed. After this phase, other
operations like rename detection and maildir flags synchronization are
performed, but the user is not informed about them. Since these
operations can take significant time, we want to inform the user about
them.

This patch enhances the progress reporting facility that was already
present. The timer that triggers reporting is not stopped after the
first phase but continues to run until all operations are finished. The
rename detection and maildir flag synchronization are enhanced to report
their progress.
2011-01-26 22:10:11 +10:00
Michal Sojka
7c450905e4 new: Add all initial tags at once
If there are several tags applied to the new messages, it is beneficial
to store them to the database at one, because it saves some time,
especially when the notmuch new is run for the first time.

This patch decreased the time for initial import from 1h 35m to 1h 14m.
2011-01-26 22:05:28 +10:00
Austin Clements
de2acbd49c Do not defer maildir flag synchronization for new messages
This is a simplified version of a patch originally by Michal Sojka
<sojkam1@fel.cvut.cz> which is designed to have the same performance
benefits. Michal said the following:

  When notmuch new is run for the first time, it is not necessary to
  defer maildir flags synchronization to later because we already know
  that no files will be removed.

  Performing the maildinr flag synchronization immediately after the
  message is added to the database has the advantage that the message
  is likely hot in the disk cache so the synchronization is faster.
  Additionally, we also save one database query for each message,
  which must be performed when the operation is deferred.

  Without this patch, the first notmuch new of 200k messages (3 GB)
  took 1h and 46m out of which 20m was maildir flags
  synchronization. With this patch, the whole operation took only 1h
  and 36m.

Unlike Michal's patch, this version does the deferral for any new
message, rather than doing it only on the first run of "notmuch new".
2011-01-26 21:52:54 +10:00
Carl Worth
73198f5c74 notmuch new: Scan directory whenever fs mtime is not equal to db mtime
Previously, we would only scan a directory if the filesystem
modification time was strictly newer than the database modification
time for the directory. This would cause a problem for systems with an
unstable clock, (if a new mail was added to the filesystem, then the
system clock rolled backward, "notmuch new" would not find the message
until the clock caught up and the directory was modified again).

Now, we always scan the directory if the modification time of the
directory is not exactly the same between the filesystem and the
database. This avoids the problem described above even with an
unstable system clock.
2010-12-05 01:40:16 -08:00
Carl Worth
38d82b07c4 notmuch new: Defer maildir_flags synchronization until after removals
When a file in the mailstore is renamed, this appears to "notmuch new"
as both an added file and a removed file (for the same message). We
want the synchronization of the maildir_flags to reflect the final
state, (after the rename is complete). Therefore, it's incorrect to
perform the synchronization immediately after adding a new
file. Instead we queue up these synchronizations (by message ID[*])
and perform them after the removals are complete.

With this change, the "dump/restore" case of the maildir-sync tests,
as well as the recent "remove 'S'" case both now pass where they were
failing before.

Interestingly, the "remove info" test was passing before, but now
fails. This is actually due to a separate bug, (and the bug just fixed
was masking it, by preventing the test from performing as desired).

[*] It's important to queue by message ID---queueing actual message
objects does not work since the message objects will retain stale data
such as the old filenames.
2010-11-11 03:40:19 -08:00
Carl Worth
bb74e9dff8 lib: Rework interface for maildir_flags synchronization
Instead of having an API for setting a library-wide flag for
synchronization (notmuch_database_set_maildir_sync) we instead
implement maildir synchronization with two new library functions:

	notmuch_message_maildir_flags_to_tags
  and   notmuch_message_tags_to_maildir_flags

These functions are nicely documented here, (though the implementation
does not quite match the documentation yet---as plainly evidenced by
the current results of the test suite).
2010-11-11 03:40:19 -08:00
Carl Worth
4cfb2a0277 Avoid abbreviation, preferring notmuch_config_get_maildir_synchronize_flags
Since the name of the configuration parameter here is:

	maildir.synchronize_flags

the convention is that the functions to get and set this parameter
should match it in name. Hence:

       notmuch_config_get_maildir_synchronize_flags

etc. (as opposed to notmuch_config_get_maildir_sync).
2010-11-11 03:40:19 -08:00