From d15ba24a2f0c177593533874ce3f4b70a47d832d Mon Sep 17 00:00:00 2001
From: Ben Burwell <ben@benburwell.com>
Date: Thu, 11 Jul 2019 09:44:53 -0400
Subject: Implement maildir copy

Create a delivery in the destination directory with the content of the
source message.
---
 worker/maildir/container.go | 38 ++++++++++++++++++++++++++++++++++++++
 worker/maildir/worker.go    |  5 +++--
 2 files changed, 41 insertions(+), 2 deletions(-)

(limited to 'worker/maildir')

diff --git a/worker/maildir/container.go b/worker/maildir/container.go
index 351afed..aa14575 100644
--- a/worker/maildir/container.go
+++ b/worker/maildir/container.go
@@ -2,6 +2,7 @@ package maildir
 
 import (
 	"fmt"
+	"io"
 	"io/ioutil"
 	"log"
 	"path/filepath"
@@ -103,3 +104,40 @@ func (c *Container) DeleteAll(d maildir.Dir, uids []uint32) ([]uint32, error) {
 	}
 	return success, nil
 }
+
+func (c *Container) CopyAll(
+	dest maildir.Dir, src maildir.Dir, uids []uint32) error {
+	for _, uid := range uids {
+		if err := c.copyMessage(dest, src, uid); err != nil {
+			return fmt.Errorf("could not copy message %d: %v", uid, err)
+		}
+	}
+	return nil
+}
+
+func (c *Container) copyMessage(
+	dest maildir.Dir, src maildir.Dir, uid uint32) error {
+	key, ok := c.uids.GetKey(uid)
+	if !ok {
+		return fmt.Errorf("could not find key for message id %d", uid)
+	}
+
+	f, err := src.Open(key)
+	if err != nil {
+		return fmt.Errorf("could not open source message: %v", err)
+	}
+
+	del, err := dest.NewDelivery()
+	if err != nil {
+		return fmt.Errorf("could not initialize delivery: %v")
+	}
+	defer del.Close()
+
+	if _, err = io.Copy(del, f); err != nil {
+		return fmt.Errorf("could not copy message to delivery: %v")
+	}
+
+	// TODO: preserve flags
+
+	return nil
+}
diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go
index f0c92ed..a5416cc 100644
--- a/worker/maildir/worker.go
+++ b/worker/maildir/worker.go
@@ -327,8 +327,9 @@ func (w *Worker) handleReadMessages(msg *types.ReadMessages) error {
 }
 
 func (w *Worker) handleCopyMessages(msg *types.CopyMessages) error {
-	// TODO: this.
-	return nil
+	defer w.done(msg)
+	dest := w.c.Dir(msg.Destination)
+	return w.c.CopyAll(dest, *w.selected, msg.Uids)
 }
 
 func (w *Worker) handleAppendMessage(msg *types.AppendMessage) error {
-- 
cgit 1.4.1-2-gfad0