1package main
2
3import (
4 "context"
5 "log"
6 "path/filepath"
7 "time"
8
9 "github.com/mjl-/bstore"
10
11 "github.com/mjl-/mox/store"
12)
13
14func cmdExportMaildir(c *cmd) {
15 c.params = "dst-dir account-path [mailbox]"
16 c.help = `Export one or all mailboxes from an account in maildir format.
17
18Export bypasses a running mox instance. It opens the account mailbox/message
19database file directly. This may block if a running mox instance also has the
20database open, e.g. for IMAP connections. To export from a running instance, use
21the accounts web page.
22`
23 args := c.Parse()
24 xcmdExport(false, args, c)
25}
26
27func cmdExportMbox(c *cmd) {
28 c.params = "dst-dir account-path [mailbox]"
29 c.help = `Export messages from one or all mailboxes in an account in mbox format.
30
31Using mbox is not recommended. Maildir is a better format.
32
33Export bypasses a running mox instance. It opens the account mailbox/message
34database file directly. This may block if a running mox instance also has the
35database open, e.g. for IMAP connections. To export from a running instance, use
36the accounts web page.
37
38For mbox export, "mboxrd" is used where message lines starting with the magic
39"From " string are escaped by prepending a >. All ">*From " are escaped,
40otherwise reconstructing the original could lose a ">".
41`
42 args := c.Parse()
43 xcmdExport(true, args, c)
44}
45
46func xcmdExport(mbox bool, args []string, c *cmd) {
47 if len(args) != 2 && len(args) != 3 {
48 c.Usage()
49 }
50
51 dst := args[0]
52 accountDir := args[1]
53 var mailbox string
54 if len(args) == 3 {
55 mailbox = args[2]
56 }
57
58 dbpath := filepath.Join(accountDir, "index.db")
59 db, err := bstore.Open(context.Background(), dbpath, &bstore.Options{Timeout: 5 * time.Second, Perm: 0660}, store.DBTypes...)
60 xcheckf(err, "open database %q", dbpath)
61 defer func() {
62 if err := db.Close(); err != nil {
63 log.Printf("closing db after export: %v", err)
64 }
65 }()
66
67 a := store.DirArchiver{Dir: dst}
68 err = store.ExportMessages(context.Background(), c.log, db, accountDir, a, !mbox, mailbox)
69 xcheckf(err, "exporting messages")
70 err = a.Close()
71 xcheckf(err, "closing archiver")
72}
73