about summary refs log tree commit homepage
path: root/lib
DateCommit message (Collapse)
2021-05-28lei: retry_reopen on read-only Xapian access
Xapian DBs may be modified by a parallel process while we're reading it, and Xapian's MVCC model places the burden on readers to retry operations. We'll also have retry_reopen croak instead of die on errors, which ought to help us track down some "Document not found" errors I've occasionally seen when using "lei <q|up>".
2021-05-28lei: restore working directory in more places
Every tick of the event loop can change the working directory, so we need to restore it for every client if they operate in different directories. This would be easier if we had openat(2) and friends in Perl; but Inline::C is practically required for lei, now.
2021-05-28lei: handle a single IMAP message in most places
"lei import" can now import a single IMAP message via <imaps://example.com/MAILBOX/;UID=$UID> Likewise, "lei inspect" can show the blob information for UID URLs and "lei lcat" can display the blob without network access if imported. "lei lcat" also gets rid of some unused code and supports "blob:$OIDHEX" syntax as described in the comments (and used by our "text" output format). v2: enforce UID in URL, fail without v3: fix error reporting (s/fail/child_error/)
2021-05-28lei_mail_sync: debug code for uncommitted txn
I'm not 100% sure why, but "lei up" seems to cause uncommitted transaction errors. LeiToMail calls sto->set_sync_info, but LeiXSearch should call sto->done and lms_commit, so I'm not sure where the uncommited transaction is coming from...
2021-05-28lei: add TODO item for FUSE mount
It seems possible and natural to allow browsing lei/store as a Maildir (as well as read-write JMAP/IMAP store).
2021-05-28lei: mark reorder-and-rewrite-local-history as a TODO item
This is low priority, for now.
2021-05-28viewdiff: escape '{' and '}' for regexp
Perl 5 doesn't warn on this, yet, but it warns on unescaped '(' and ')' nowadays, so it's conceivable Perl could start warning on this in the future. So future-proof our code and reduce reader confusion.
2021-05-28viewdiff: make $UNSAFE a variable
There's no sense in using a constant here since it gets copied into the uri_escape_utf8 function anyways. Furthermore, inlined constants still leave behind a subroutine and subs cost several KB of memory. Finally, add a comment as to why it's different than the default escape, since I just spent a minute wondering that.
2021-05-27lei rm: new command to remove messages from index
This is similar to "public-inbox-learn rm", but it's possible to point an entire Maildir/IMAP/mbox*/newsgroup at it.
2021-05-26lei: require Socket::MsgHdr or Inline::C, drop oneshot
The cost of supporting separate code paths between oneshot and daemon isn't worth the trouble; especially if there are more users to support. The test suite time nearly doubles with oneshot, so that's hurting developer productivity. FD passing is currently required to work efficiently with remote HTTP(S) queries which return large messages, as seen in commit 708b182a57373172f5523f3dc297659d58e03b58 ("ipc: wq: handle >MAX_ARG_STRLEN && <EMSGSIZE case"). Additionally, upcoming support for IMAP IDLE and inotify-based monitoring of Maildirs cannot work properly without a background daemon.
2021-05-25ipc: wq: handle >MAX_ARG_STRLEN && <EMSGSIZE case
WQWorkers are limited roughly to MAX_ARG_STRLEN (the kernel limit of argv + environ) to avoid excessive memory growth. Occasionally, we need to send larger messages via workqueues that are too small to hit EMSGSIZE on the sender. This fixes "lei q" when using HTTP(S) externals, since that code path sends large Eml objects from lei_xsearch workers directly to lei2mail WQ workers.
2021-05-25ipc: avoid potential stack-not-refcounted bug
This fixes a potential problem with Carp::longmess firing somewhere deeper in the stack. This is not a known problem at this time, but something I noticed while chasing something else.
2021-05-25lei forget-mail-sync: new command to drop sync information
Sometimes a user stops caring to sync an IMAP or Maildir folder, or wants to force a resync. Let them run this command to have lei forget all the sync information about the mail folder. This won't delete any stored messages in git, but will leave "lei index" users with dangling references.
2021-05-25lei_mail_sync: args2folder: common folder lookup sub
This lets us have a more consistent UX for mapping easily-typed command-line arguments to canonical folder locations.
2021-05-25lei export-kw: use lei->abs_path instead of rel2abs
This is to match LeiInput behavior when mail-sync is enabled, since rel2abs won't resolve symlinks.
2021-05-25lei export-kw: fix case-insensitivity typo for IMAP URLs
Fixes: a9bfba8eb31dbb4c ("lei inspect: use LeiMailSync->match_imap_url")
2021-05-24lei_mail_sync: reject IMAP URLs w/o UIDVALIDITY
It's inappropriate to store sync information without UIDVALIDITY, so add an assertion to prevent it.
2021-05-24lei inspect: use LeiMailSync->match_imap_url
Move match_imap_url into LeiMailSync so it can be used in more places, such as "lei inspect". Upcoming commands such as "lei forget-mail-sync" and {add,forget,pause,resume}-watch will also support relaxed IMAP matching rules since there's no reasonable way to expect users use ";UIDVALIDITY=" on the command-line.
2021-05-23lei <q|up>: set \Recent on non-empty mbox and Maildir
Despite JMAP not supporting the equivalent of the IMAP \Recent flag, it is useful for "lei q --augment", and "lei up" users to be able to distinguish new results from old-but-unread messages in an mbox or Maildir. For mbox family messages, we'll drop the "O" status flag when appending to mboxes, and we'll write to the "new" subdirectory of Maildirs. Behavior when writing to initially empty Maildirs and mboxes remains unchanged since there's no need to distinguish between new and old results in the initial case. Having users wait for a rename(2) storm or complete mbox rewrite hurts UX. With IMAP mailboxes, \Recent is already enforced by the IMAP server and IMAP clients have no way of changing it(*) (*) mutt uses the "Old" IMAP flag which isn't part of RFC 3501, other MUAs may do similar things.
2021-05-23lei export-kw: relax IMAP URL matching
It's unreasonable to expect UIDVALIDITY= to be specified in command-line arguments. We'll also check for cases without "$USER@" or ";AUTH=", since we accept those forms on the command-line.
2021-05-23lei export-kw: support exporting keywords to IMAP
We support writing to IMAP stores in other places (just like Maildir), and it's actually less complex for us to write to IMAP. Neither usability nor performance is ideal, but usability will be addressed in the next commit to relax CLI argument checking. Performance is poor due to the synchronous Mail::IMAPClient API and will need to be addressed with pipelining sometime further in the future.
2021-05-23net_reader|net_writer: pass URI refs deeper into callbacks
This will give us more flexibility in the future w.r.t. dealing with UIDVALIDITY and AUTH= info with IMAP. The LoC reduction is welcome, too.
2021-05-23lei import: store IMAP user+auth in mail_sync folder URI
Just having UIDVALIDITY in the URI isn't enough, since a single lei user may have multiple IMAP logins on the same server. This leads to compatibility problems and forces a reimport for the few users already using this lei functionality, but it's not stable nor released, yet.
2021-05-23uri_imap: support uid/auth/user as full accessors
We will need this for mail synchronization
2021-05-23lei export-kw: new command to export keywords to Maildirs
IMAP will eventually be supported.
2021-05-23lei index: support command-line options
This mostly takes after "lei import", and at least --quiet needs to be supported.
2021-05-23lei_input: fix canonicalization of Maildirs for sync
This is needed for the upcoming "lei export-kw"
2021-05-23lei tag: support tagging index-only messages
This will make some of our tests faster and allow users to try more features of lei without high storage requirements.
2021-05-23lei: drop EOFpipe in favor of PktOp
lei already uses PktOp and SOCK_SEQPACKET throughout; whereas EOFpipe had one single use in lei. Since PktOp is a strict superset of EOFpipe functionality, we may be able to get rid of EOFpipe entirely. However, lei is considered a portability canary and I'm not sure if the stable public-inbox-* code can drop EOFpipe just yet.
2021-05-23treewide: favor open(..., '+<&=', $fd)
Cut down on unnecessary imports of IO::Handle and method lookup + dispatch overhead.
2021-05-21lei rediff: fix construction of git-diff options
When generating git-diff options, lei-rediff extracts the single character option from the lei option spec. However, there's no check that the regular expression actually matches, leading to an unintentional git-diff option when there isn't a short option (e.g., --inter-hunk-context=1 maps to the invalid `git diff --color -w1'). Check for a match before trying to extract the single character option. Fixes: cf0c7ce3ce81b5c3 (lei rediff: regenerate diffs from stdin)
2021-05-19lei: relax rules for "new" in Maildir
mbsync and offlineimap both use ":2," suffixes for filenames in "new/", however my interpretation of the Maildir spec at <https://cr.yp.to/proto/maildir.html> is that ":2," is only for files in "cur/". My interpretation also matches that of doveecot, but we'll allow what mbsync and offlineimap do given their popularity.
2021-05-17lei lcat: fix handling of multiple MSGID_OR_URL arguments
`lei lcat' is documented as being able to display multiple messages, but this works only with --stdin because the positional argument MSGID_OR_URL is missing a period.
2021-05-16lei rediff: handle stdin like other commands
`lei rediff' reads from stdin when no argument is specified, but this is likely unintentional given that other lei commands instead have a --stdin|- option and that `lei rediff --help' includes --stdin. Align rediff's handling with the other commands'.
2021-05-16lei rediff: mark --color-moved value as optional
`git-diff --color-moved' can be called without a mode, in which case it defaults to "zebra".
2021-05-16lei_input: drop misplaced word from error message
2021-05-15dir_idle: support IN_DELETE_SELF|IN_MOVE_SELF, too
We'll treat IN_MOVE_SELF as IN_DELETE_SELF since there doesn't seem to be a reliable way to distinguish them with FakeInotify, nor know the new name with kevent.
2021-05-15dir_idle: detect files which are gone
lei now makes use of this to clean up after unlinked sockets with less delay. This will also be used to maintain mail_sync.sqlite3.
2021-05-15lei_mail_sync: do not disable CoW for this DB
This is rather critical data for synchronization, especially when "lei index" is used instead of "lei import"
2021-05-09git: fix numerous bugs in git_quote and git_unquote
git always quotes with leading zeros to ensure the octal representation is 3 characters long. We enforce that to match low ASCII characters (e.g. [x01-\x06]) that don't need the range provided by 3 characters. git_unquote now does a single pass so it won't get fooled by decoded backslashes into parsing a digit as an octal character. git_unquote is also capped to "\377" so we don't overflow a byte.
2021-05-06syscall: minor yak-shaving updates
FreeBSD (and other *BSDs) do not have stable syscall numbers, so drop no-op checks for it and add a note to use Inline::C, instead. Drop an implicit return for the syscall.ph loading while we're at it, too. On Linux, epoll_create(2) ignores the size arg since Linux 2.6.8, so just hard code it to some non-zero value. On a side note, we can probably drop epoll_create(2) support soon and just use epoll_create1(2) which appeared in 2.6.27+ (2008-10-09). Our userspace (Perl and git) requirements are already further ahead.
2021-05-06lei_xsearch: fix accounting bugs in for remote mboxrd
We must not accumulate mset totals for messages which have already been counted. Furthermore, the combined search was being passed an extra arg and causing the total to go missing.
2021-05-06lei_mail_sync: Maildir canonicalization omits trailing slash
We use trailing slashes internally, but should not increase visual noise for users by exposing them in config files or DB storage (and shell completion/listings). This fixes a long-standing bug in $lei->rel2abs that prevented absolute paths from being canonicalized.
2021-05-06lei_rediff: reduce overhead of tmp store
We don't need Xapian positional info when searching for blob pre/post-images. Furthermore, rediff will usually be used for a single email or at most, one patchset. So there's little point in parallelizing or having multiple shards.
2021-05-05lei rediff: do not automatically store patches/mails
We can use a temporary lei/store to avoid cluttering up future search results. This is especially useful since we expect "lei rediff" to be useful for non-email diffs and individual attachments, too.
2021-05-05lei rediff: capture and regenerate file modes
Don't lose file mode information when regenerating a diff.
2021-05-05lei blob: support "lei index"-ed mail
Normal git retrieval don't work for Maildir blobs indexed using "lei index". Fortunately, this oddness is limited to the LeiStore class and we can override smsg_eml with a fallback to read blobs from Maildirs.
2021-05-05lei rediff: regenerate diffs from stdin
Sometimes a mailed patch is generated with non-ideal output, (lacking context, noisy whitespace changes, etc.), or a user wants to use the same external diff viewer they've configured git to use. Since we have SolverGit to regenerate arbitrary blobs from patches; this new command allows us to regenerate a diff with different options using the blobs SolverGit gives us. The amount of git-diff(1) options is mind numbing, so it's likely I missed some favorites or botched the getopt spec translation. This also fixes Inbox::base_url to check psgi.url_scheme before attempting to generate URLs and avoid uninitialized variable warnings. Oddly, the "lei blob" tests did not trigger these uninitialized warnings. Note: this will automatically import+index the message(s) it's regenerating, because solver relies on being able to lookup pre/postimage OIDs and read blobs.
2021-05-04lei index: new command to index mail w/o git storage
Since completely purging blobs from git is slow, users may wish to index messages in Maildirs (and eventually other local storage) without storing data in git. Much code from LeiImport and LeiInput is reused, and a new dummy FakeImport class supplies a non-storing $im->add and minimize changes to LeiStore. The tricky part of this command is to support "lei import" after a message has gone through "lei index". Relying on $smsg->{bytes} == 0 (as we do for external-only vmd storage) does not work here, since it would break searching for "z:" byte-ranges when not using externals. This eventually required PublicInbox::Import::add to use a SharedKV to keep track of imported blobs and prevent duplication.
2021-05-04lei: fix mail_sync.sqlite3 folder names for NNTP
We should not have "SCALAR(XXXXXXX)" showing up in SQLite DBs because we passed a SCALAR ref instead of a non-ref SCALAR.