lots of small improvements
2 files changed, 34 insertions(+), 34 deletions(-)

M command.go
M edit.go
M command.go +18 -18
@@ 1,15 1,15 @@ 
 package mailbox
 
 import (
-	"bufio"
+	"bytes"
 	"errors"
+	"fmt"
 	"io"
 	"io/ioutil"
 	"mime"
 	"mime/multipart"
 	"net/mail"
 	"os"
-	"path"
 	"strconv"
 	"strings"
 

          
@@ 60,7 60,7 @@ func Store(mb Mailbox, msg io.Reader, fo
 }
 
 func partError(no int, msg string) error {
-	return errors.New("part " + strconv.Itoa(no) + ": " + msg)
+	return errors.New("mime part " + strconv.Itoa(no) + ": " + msg)
 }
 
 func Save(files chan string, msg *mail.Message, number int) error {

          
@@ 76,14 76,11 @@ func Save(files chan string, msg *mail.M
 		if len(filename) == 0 {
 			return partError(no, "no filename")
 		}
-		basename := path.Base(filename)
-		if len(basename) == 0 {
-			return partError(no, "invalid filename '"+filename+"'")
-		}
 		f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666)
 		if err != nil {
 			return partError(no, err.Error())
 		}
+		defer f.Close()
 		in, err := mimeDecoder(p)
 		if err != nil {
 			return partError(no, err.Error())

          
@@ 91,12 88,13 @@ func Save(files chan string, msg *mail.M
 		if _, err = io.Copy(f, in); err != nil {
 			return partError(no, err.Error())
 		}
-		files <- basename
-		return nil
+		files <- f.Name()
+		return f.Close()
 	}
 	return parse(msg, saver)
 }
 
+// todo: print something like "inbox/33:1 <header>"?
 func Parts(parts chan string, msg *mail.Message) error {
 	partsLister := func(p part, no int) error {
 		parts <- p.Header.Get("Content-Type")

          
@@ 122,9 120,10 @@ func ViewPart(dst io.Writer, msg *mail.M
 
 func newPlainTextPrinter(dst io.Writer, t transform.Transformer) func(part, int) error {
 	return func(p part, no int) error {
+		// todo: if the msg has no content type header, this will return "mime: no media type"
 		mt, _, err := mime.ParseMediaType(p.Header.Get("Content-Type"))
 		if err != nil {
-			return err
+			return errors.New("parsing media type: " + err.Error())
 		}
 		if strings.HasPrefix(mt, "text/plain") {
 			in, err := mimeDecoder(p)

          
@@ 134,8 133,9 @@ func newPlainTextPrinter(dst io.Writer, 
 			_, err = io.Copy(dst, transform.NewReader(in, t))
 			return err
 		}
-		io.WriteString(dst, "[MIME Part "+strconv.Itoa(no)+": ")
-		io.WriteString(dst, p.Header.Get("Content-Type")+"]\n ")
+		if _, err = fmt.Fprintf(dst, "[MIME Part %d: %s]\n", strconv.Itoa(no), p.Header.Get("Content-Type")); err != nil {
+			return err
+		}
 		// process the stream (by throwing it away), as it is replaced by the string above
 		_, err = io.Copy(ioutil.Discard, p.Body)
 		return err

          
@@ 145,13 145,13 @@ func newPlainTextPrinter(dst io.Writer, 
 // if the mail has only one header line without a nl at the end, "mailbox: EOF"
 // is thrown
 func View(dst io.Writer, msg *mail.Message) error {
-	out := bufio.NewWriter(dst)
-	defer out.Flush()
 	dec := newDecoder()
+	var b bytes.Buffer
 	for _, key := range viewHeader {
-		out.WriteString(key + ": " + dec.safeDecodeHeader(msg.Header.Get(key)) + "\n")
+		b.WriteString(key + ": " + dec.safeDecodeHeader(msg.Header.Get(key)) + "\n")
 	}
-	// bug: if we dont have a mime msg, this will return "mime: no media type"
-	// so we should first check if we have a mime msg
-	return parse(msg, newPlainTextPrinter(out, transform.Nop))
+	if _, err := io.Copy(dst, &b); err != nil {
+		return err
+	}
+	return parse(msg, newPlainTextPrinter(dst, transform.Nop))
 }

          
M edit.go +16 -16
@@ 219,8 219,8 @@ func forwardMsg(dst io.Writer, from stri
 	if ct := msg.Header.Get("Content-Type"); len(ct) > 0 {
 		fmt.Fprintf(&b, "Content-Type: %s\n", ct)
 	}
-	fmt.Fprintf(&b, "\n\n\nBegin forwarded message:\n\n\n"+
-		"Date: %s\nFrom: %s\nTo: %s\nCc: %s\nSubject: %s\n\n", dec.safeDecodeHeader(msg.Header.Get("Date")),
+	b.WriteString("\n\n\nBegin forwarded message:\n\n\n")
+	fmt.Fprintf(&b, "Date: %s\nFrom: %s\nTo: %s\nCc: %s\nSubject: %s\n\n", dec.safeDecodeHeader(msg.Header.Get("Date")),
 		parseAddressList(msg.Header.Get("From")), parseAddressList(msg.Header.Get("To")),
 		parseAddressList(msg.Header.Get("Cc")), subject)
 

          
@@ 269,22 269,22 @@ func parseAddressList(list string) strin
 	if len(list) == 0 {
 		return ""
 	}
-
 	addrList, err := mail.ParseAddressList(list)
 	if err != nil {
 		return "Error: " + err.Error()
 	}
-	var b bytes.Buffer
+	var s string
 	for i := range addrList {
 		if i > 0 {
-			b.WriteString(", ")
+			s += ", "
 		}
-		b.WriteString(addrList[i].Name)
-		b.WriteString(" <")
-		b.WriteString(addrList[i].Address)
-		b.WriteString(">")
+		sa := addrList[i].Address
+		if sn := addrList[i].Name; len(sn) > 0 {
+			sa = sn + " <" + sa + ">"
+		}
+		s += sa
 	}
-	return b.String()
+	return s
 }
 
 func readIntoMimeMessage(src io.Reader) (*mail.Message, error) {

          
@@ 306,17 306,17 @@ func readIntoMimeMessage(src io.Reader) 
 	// h.Write never returns an error
 	io.WriteString(h, strconv.Itoa(time.Now().Nanosecond()))
 	b = fmt.Sprintf("%x", h.Sum(nil))
-
-	mhdr := strings.NewReader(fmt.Sprintf("\r\n--%s\r\n"+
+	var mhdr bytes.Buffer
+	fmt.Fprintf(&mhdr, "\r\n--%s\r\n"+
 		"Content-Type: %s\r\n"+
 		"Content-Transfer-Encoding: %s\r\n"+
 		"Content-Disposition: inline\r\n\r\n",
-		b, hdr.Get("Content-Type"), hdr.Get("Content-Transfer-Encoding")))
+		b, hdr.Get("Content-Type"), hdr.Get("Content-Transfer-Encoding"))
 
 	hdr.Del("Content-Transfer-Encoding")
 	hdr.Set("Content-Type", "multipart/mixed; boundary="+b)
 	hdr.Set("Mime-Version", "1.0")
-	return &mail.Message{mail.Header(hdr), io.MultiReader(mhdr, src)}, nil
+	return &mail.Message{mail.Header(hdr), io.MultiReader(&mhdr, src)}, nil
 }
 
 func boundary(hdr textproto.MIMEHeader) (string, error) {

          
@@ 342,7 342,7 @@ func Attach(mbox Mailbox, dst io.Writer,
 	}
 	buf := bufio.NewWriter(dst)
 	defer buf.Flush()
-	// todo: writeHeader uses a buffer by itself
+
 	if err = writeHeader(buf, msg.Header); err != nil {
 		return fmt.Errorf("writing msg header: %s", err)
 	}

          
@@ 410,7 410,7 @@ func (w *lineWriter) Write(b []byte) (in
 	}
 	for len(b) > w.free {
 		n += write(b[:w.free])
-		// don't count the \r\n, these bytes do not come from b
+		// don't count \r\n, these bytes do not come from b
 		write([]byte("\r\n"))
 		b = b[w.free:]
 		w.free = w.maxwidth