sent first mail with mailbox!
6 files changed, 46 insertions(+), 27 deletions(-)

M cmd/mb/main.go
M command.go
M config.go
M edit.go
M parse.go
M send.go
M cmd/mb/main.go +14 -2
@@ 252,8 252,20 @@ func main() {
 		// todo: implement this
 		err = errors.New(cmd + ": not implemented")
 	case "send":
-		// todo: dont forget to strip bcc header
-		err = errors.New(cmd + ": not implemented")
+		var src io.ReadCloser = os.Stdin
+		if len(os.Args) > 2 {
+			if src, err = openMsg(mbox, os.Args[2]); err != nil {
+				break
+			}
+		}
+		var msg *mail.Message
+		if msg, err = mail.ReadMessage(src); err != nil {
+			src.Close()
+			break
+		}
+		if err = mb.Send(msg); err != nil {
+			// todo: move msg from draft to sent
+		}
 	case "mv":
 		// todo: defaultfolder
 		if len(os.Args) < 4 {

          
M command.go +4 -0
@@ 161,3 161,7 @@ func View(dst io.Writer, msg *mail.Messa
 	}
 	return parse(msg, newPlainTextPrinter(dst, transform.Nop))
 }
+
+func Send(msg *mail.Message) error {
+	return sendWithSsmtp(msg, sendmailConfig)
+}

          
M config.go +3 -0
@@ 44,4 44,7 @@ var (
 	defaultFolderType = inbox
 
 	listDelim = " | "
+
+	// todo:
+	sendmailConfig = "/home/schlichti/.etc/ssmtp/mailbox.gmx.conf"
 )

          
M edit.go +0 -1
@@ 420,7 420,6 @@ func (w *lineWriter) Write(b []byte) (in
 	return n, err
 }
 
-// todo: dont write bcc when sending
 func writeHeader(dst io.Writer, h map[string][]string) error {
 	enc := mime.QEncoding
 	var b bytes.Buffer

          
M parse.go +2 -2
@@ 59,9 59,9 @@ func mimeDecoder(p part) (io.Reader, err
 		// but we are save, as multipart.Part removes silently this
 		// header key, so this case cannot happen. still this feels fragile.
 		// see // http://golang.org/src/mime/multipart/multipart.go
-		out = qp.NewReader(out)
+		out = qp.NewReader(p.Body)
 	case "base64":
-		out = base64.NewDecoder(base64.StdEncoding, out)
+		out = base64.NewDecoder(base64.StdEncoding, p.Body)
 	default:
 		// "7bit", "8bit", "binary" and none-mime emails: nothing to do
 		out = p.Body

          
M send.go +23 -22
@@ 1,36 1,45 @@ 
 package mailbox
 
 import (
+	"fmt"
 	"io"
-	qp "mime/quotedprintable"
-	"net/textproto"
+	"net/mail"
 	"os"
 	"os/exec"
 	"strings"
 )
 
-func ssmtpSender(header textproto.MIMEHeader, body io.Reader) error {
+func sendWithSsmtp(msg *mail.Message, configfile string) error {
 
-	rcpts := append(extract(header.Get("To")), extract(header.Get("Cc"))...)
-	rcpts = append(rcpts, extract(header.Get("Bcc"))...)
+	h := msg.Header
+	var rcpts []string
+	for _, key := range []string{"To", "Cc", "Bcc"} {
+		if rcpt := extract(h.Get(key)); len(rcpt) > 0 {
+			rcpts = append(rcpts, rcpt...)
+		}
+	}
+	delete(msg.Header, "Bcc")
 	// todo: remove -v
-	args := append([]string{"-v", "-C", "/home/schlichti/.etc/ssmtp/gmx.conf"}, rcpts...)
+	args := append([]string{"-v", "-C", configfile}, rcpts...)
+	fmt.Fprintf(os.Stderr, "%q", args)
 	cmd := exec.Command("/usr/sbin/ssmtp", args...)
 	// todo: maybe use a pipe for both outputs?
 	cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
 	stdin, err := cmd.StdinPipe()
+	if err != nil {
+		return err
+	}
+	defer stdin.Close()
 	if err := cmd.Start(); err != nil {
 		// todo: check when the error here occurs, like use a non existing prog
 		return err
 	}
-	// todo: encode and write header (except bcc)
-	// todo: remove bcc
-	// finish header
-	stdin.Write([]byte{'\n'})
+	// write header
+	if err = writeHeader(stdin, msg.Header); err != nil {
+		return err
+	}
 	// write body
-	// todo: attachments, text quoted, others base64
-	if _, err = io.Copy(stdin, qp.NewReader(body)); err != nil {
-		// todo: clean up
+	if _, err = io.Copy(stdin, msg.Body); err != nil {
 		return err
 	}
 	// close stdin so the command can exit

          
@@ 38,15 47,7 @@ func ssmtpSender(header textproto.MIMEHe
 		// really return? first cmd.Wait() maybe?
 		return err
 	}
-	if err := cmd.Wait(); err != nil {
-		return err
-	}
-	return nil
-
-}
-
-func ssmtp() (func(textproto.MIMEHeader, io.Reader) error, error) {
-	return nil, nil
+	return cmd.Wait()
 }
 
 func extract(list string) (addrs []string) {