When moving/copying/deleting/archiving a message in imap, the RUE counts
displayed in the dirlist would not update properly. Maildir has (had) an
implementation that recounts the entire directory and updates the
DirectoryInfo after one of these actions.
This patch implements a more efficient method of updating, and also
enables it to apply to IMAP without any additional requests. Upon
completion of the action, the counts are manually updated with the count
of messages in the action and recent and/or unseen states of those
messages. This is more efficient for maildir, because we aren't counting
everything in the store. For IMAP, we get the updates for free because
we are only performing the update after confirmation from the server
that the action has happened.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Check for new mail (recent, unseen, exists counts) with an external
command, or for imap with the STATUS command, at start or on
reconnection and every X time duration
IMAP:
The selected folder is skipped, per specification. Additional config
options are included for including/excluding folders explicitly.
Maildir/Notmuch:
An external command will be run in the background to check for new mail.
An optional timeout can be used with maildir/notmuch. Default is 10s
New account options:
check-mail
check-mail-cmd (maildir/notmuch only)
check-mail-timeout (maildir/notmuch only), default 10s
check-mail-include (IMAP only)
check-mail-exclude (IMAP only)
If unset, or set less than or equal to 0, check-mail will be ignored
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
Extract the tcp connection details and timeout the tcp connect functions
(net.ResolveTCPAddr and net.DialTCP). If timed out, ensure that the
connection is properly closed.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Add a debouncer to the idle mode. Avoid unnecessary idling when another
job arrives within a certain time frame.
For example, the ui sends three messages to the worker at the same time
when we open a message (FlagMessage, FetchMessageBodyPart, and the
FetchMessageHeaders). The debouncer prevents the unnecessary entering
and leaving of the idle mode between those messages.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Untangle the observer functionality from the message handling routine.
Observe the imap client's logout channel and trigger a connection error
when necessary to start the reconnect cycle.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Untangle the idle functionality from the message handling routine. Wait
for the idle mode to properly exit every time to ensure a consistent
imap state. Timeout when hanging in idle mode and inform the ui.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Extract the imap config and move the configure part out of the message
handler.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Check slice bounds before using it for the message and expunge updates.
Log the error but ignore the affected updates.
Link: https://lists.sr.ht/~rjarry/aerc-devel/%3CCJEHBFFUI11T.1AYGOMVGZ87ZS%40rek2system%3E
Reported-by: ReK2 <rek2@hispagatos.org>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
When running `:reply -q` on an unread message, aerc crashes after
opening the editor:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5d1019]
goroutine 63 [running]:
bufio.(*Reader).fill(0xc000086ef8)
/usr/lib/golang/src/bufio/bufio.go:106 +0xd9
bufio.(*Reader).Peek(0xc00020bef8, 0x1)
/usr/lib/golang/src/bufio/bufio.go:144 +0x5d
github.com/emersion/go-message/textproto.ReadHeader(0xc00004a700?)
emersion/go-message@v0.15.0/textproto/header.go:525 +0x5f
git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleFetchMessageBodyPart.func1(0xc00056e280)
worker/imap/fetch.go:99 +0x1ab
git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleFetchMessages.func1()
worker/imap/fetch.go:178 +0xd7
created by git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleFetchMessages
worker/imap/fetch.go:172 +0x12b
This happens because the flags are updated in the callback that receives
the message itself. It causes the flag update to arrive in the same
channel/request. Ignore the messages that have an empty body (i.e. only
containing flag updates). This is inherently racy but there seems no way
to get rid of these extra messages.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Connor Kuehl <cipkuehl@gmail.com>
Ensure CRLF line endings in the pgpmail reader. Fix the pgp signature
verification for maildir and notmuch.
These backends do not return the full message body with CRLF
line endings. But the accepted OpenPGP convention is for signed data to
end with a <CR><LF> sequence (see RFC3156).
If this is not the case the signed and transmitted data are considered
not the same and thus signature verification fails.
Link: https://datatracker.ietf.org/doc/html/rfc3156
Reported-by: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Since panics still regularly "destroy" the terminal, it is hard to get a
stack trace for panics you do not anticipate. This commit adds a panic
handler that automatically creates a logfile inside the current working
directory.
It has to be added to every goroutine that is started and will repair
the terminal on a panic.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit fixes all occurrences of the abovementioned lint-error in
the codebase.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Apply the user-defined sort criteria to the message with the highest
uid in a threaded discussion. Restore the default sort order when
leaving threading mode.
Commit 7811620eb8 ("threading: implement on-the-fly message
threading") introduced message threading with the threaded messages
being only sorted by their message uids irrespective of the defined sorting
criteria. It did not restore the default sort order either.
Reported-by: Sebastien Binet <s@sbinet.org>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Fix a data race due dirInfo pointer being read in the main goroutine
by NewMessageStore and written in the anonymous goroutine launched in
Worker.getDirectoryInfo.
To address the issue raised in https://todo.sr.ht/~rjarry/aerc/16, we
use readdir(3) once, parse and cache its results, this replaces
go-maildir library Dir.Flags based stat(3) and filepath.Glob
causing the issue when N (emails) is large.
Signed-off-by: wagner riffel <w@104d.net>
implement message threading on the message store level using the
jwz algorithm. Build threads on-the-fly when new message headers arrive.
Use the references header to create the threads and the in-reply-to
header as a fall-back option in case no references header is present.
Does not run when the worker provides its own threading (e.g. imap
server threads).
Include only those message headers that have been fetched and are
stored in the message store.
References: https://www.jwz.org/doc/threading.html
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Inwit <inwit@sindominio.net>
Tested-by: akspecs <akspecs@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Start the reconnect cycle when the initial connect fails. Make the
connection observer send a connection error when the imap client is nil.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
waits an increasing amount of time before attempting a reconnect.
Wait is capped at 16s. Prevents many reconnect attemps in a short time period.
Fixes commit 05ad96a30c ("imap: improve reconnect stability") that
improved the reliability of the reconnect mechanism but did not
implement controls to prevent the triggering of too many reconnects
within a short period of time.
Fixes: 05ad96a30c ("imap: improve reconnect stability")
Signed-off-by: Koni Marti <koni.marti@gmail.com>
improves the robustness of the imap reconnect feature which was
introduced in commit beae17a6da ("imap: auto-reconnects on connection
error").
If a connection error is emitted, the message list is cleared and a
corresponding error message is shown in the ui. Status bar is updated as
well. Upon reconnect, the directories and the message list will be
re-fetched (same behavior as the connect command).
Reconnect can be enabled and disabled with the connect and the
disconnect commands.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Some messages contain invalid headers, textproto.ReadHeader fails with
an error:
malformed MIME header key: From nobody Fri Jan 14 19
And all other messages of the selected folder are ignored.
Return an explicit error message to the UI and continue processing other
messages. This is consistent with what the maildir worker does.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Since commit 01c96e78df ("Update DirectoryInfo handling for maildir"),
flags are checked for every message of a folder when entering it.
Iterating over all messages of a folder takes a long time for large
collections of emails.
Only count the number of messages and state that the directory info
counts are not accurate. Defer the parsing of message flags in
a goroutine to have a more responsive UI.
Fixes: https://todo.sr.ht/~rjarry/aerc/16
Suggested-by: Koni Marti <koni.marti@gmail.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
This fixes piped full message (:pipe -m) being empty.
Fixes: 904ffacb0e ("maildir,notmuch: avoid leaking open files")
Signed-off-by: Nguyễn Gia Phong <mcsinyx@disroot.org>
Previously, Message.NewReader returned the wrapped buffered reader
without a reference to the opened file, so the files descriptors
were left unclosed after reading. Now, the file reader is returned
directly and closed on the call site. Buffering is not needed here
because it is an implementation detail of go-message.
Fixes: https://todo.sr.ht/~rjarry/aerc/9
if the worker emits a connection error, the ui will automatically send back a
reconnect command. The worker then establishes a new connection. Auto-reconnect
is disabled when the user sends the disconnect command.
Fixes: https://todo.sr.ht/~rjarry/aerc/1
Signed-off-by: Koni Marti <koni.marti@gmail.com>
implements a new connection error message. This allows the worker to emit a
connection-related error message to the ui when the imap client closes the
loggedOut channel.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
fixes the panic when the user sends multiple connect commands and is
already connected. The panic is caused by closing an already closed
channel. This happens when the idle re-init code is not executed, e.g.
when there's a return statement in the switch block. A defer func()
before the switch block will prevent this. The existing behavior of only
creating a new idleStop channel when properly connected is preseverd.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
This reverts commit c605ada3dd.
This breaks reading message bodies. I am not sure why, I'll take some
time to fix it later.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Attempt to reconnect to the server when there is an unexpected
disconnection or network error.
Use the Client.LoggedOut() channel which is closed when the connection
is closed.
This patch is rather flaky and is certainly bugged. However, it is
a start.
Signed-off-by: Robin Jarry <robin@jarry.cc>
There was a change in how build tags are formatted. Use this as new
reference.
Link: https://go.dev/doc/go1.17#gofmt
Signed-off-by: Robin Jarry <robin@jarry.cc>
Fix the following build error on mac os:
worker/imap/worker.go:368:29: undefined: syscall.TCP_KEEPCNT
worker/imap/worker.go:376:29: undefined: syscall.TCP_KEEPINTVL
These symbols are not defined on darwin.
Fixes: 5dfeff75f3 ("imap: add tcp connection options")
Signed-off-by: Robin Jarry <robin@jarry.cc>
In preparation for tcp keepalive options, we need access to the
net.TCPConn object associated with an IMAP connection. The only way to
do this is to create the connection ourselves.
No functional change.
Signed-off-by: Robin Jarry <robin@jarry.cc>
This will prepare for extra tcp connection options support and for
automatic reconnect. No functional change.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Messages flags can also be changed without changing directories.
Changing flags in maildirs means renaming the message files. Also take
renames into account.
Link: https://cr.yp.to/proto/maildir.html
Fixes: f4d3c8fc77 ("maildir: watch for external changes")
Signed-off-by: Robin Jarry <robin@jarry.cc>
When a maildir is synchronized by an external process while aerc is
running (e.g. mbsync), some emails may be moved out of "new" to "cur" or
completely deleted.
These deletions are ignored and aerc may assume these messages are still
here, leading to errors.
Take file deletions into account. Also, add "cur" to the watched
folders since these can be modified as well.
Signed-off-by: Robin Jarry <robin@jarry.cc>
When using the notmuch backend, it often makes more sense to sort
folders (actual virtual folders, or queries) by the order specified in
the query-map file, rather than alphabetically. This patch introduces a
configuration option (disabled by default) that allows this.
Additionally, due to the notmuch backend previously using maps (which
are order-undefined) to store the list of queries, default query
selection on aerc startup fluctuated. This patch fixes that by using
slices to store query order.
Display threads in the message list. For now, only supported by the
notmuch backend and on IMAP when the server supports the THREAD
extension.
Setting threading-enable=true is global and will cause the message list
to be empty with maildir:// accounts.
Co-authored-by: Kevin Kuehler <keur@xcf.berkeley.edu>
Co-authored-by: Reto Brunner <reto@labrat.space>
Signed-off-by: Robin Jarry <robin@jarry.cc>
In the maildir worker we manually need to track the Recent flag in order for the
notification command etc to work.
Push that responsibility to the container, we must make sure to manually add the
flag though if one grabs the message info.
We frequently had issues with notmuch segfaulting and my guess is that this
was due to the garbage collection magic used in the module.
This changes to a fork that ripped the functionality out.