fix attach
3 files changed, 40 insertions(+), 24 deletions(-)

M cmd/mb/main.go
M command.go
M edit.go
M cmd/mb/main.go +16 -10
@@ 195,17 195,24 @@ func main() {
 			os.Stdout.WriteString(name + "\n")
 		}
 	case "attach":
+		// todo: 1..n files
 		if len(os.Args) < 4 {
 			err = missingParams
 			break
 		}
 		var src io.ReadCloser = os.Stdin
-		if len(os.Args) > 2 {
+		if len(os.Args) > 3 {
 			if src, err = openMsg(mbox, os.Args[2]); err != nil {
 				break
 			}
 		}
 		err = mb.Attach(mbox, os.Stdout, src, os.Args[3])
+		if err1 := src.Close(); err == nil {
+			err = err1
+		}
+	case "detach":
+		// todo.
+		os.Stdout.WriteString("todo!\n")
 	case "reply": // is a reply-all
 		var src io.ReadCloser = os.Stdin
 		if len(os.Args) > 2 {

          
@@ 222,11 229,9 @@ func main() {
 		if name, err = mb.Reply(mbox, msg); len(name) > 0 {
 			os.Stdout.WriteString(name + "\n")
 		}
-		if err != nil {
-			src.Close()
-			break
+		if err1 := src.Close(); err == nil {
+			err = err1
 		}
-		err = src.Close()
 	case "forward":
 		var src io.ReadCloser = os.Stdin
 		if len(os.Args) > 2 {

          
@@ 243,11 248,9 @@ func main() {
 		if name, err = mb.Forward(mbox, msg); len(name) > 0 {
 			os.Stdout.WriteString(name + "\n")
 		}
-		if err != nil {
-			src.Close()
-			break
+		if err1 := src.Close(); err == nil {
+			err = err1
 		}
-		err = src.Close()
 	case "edit":
 		// todo: implement this
 		err = errors.New(cmd + ": not implemented")

          
@@ 266,6 269,9 @@ func main() {
 		if err = mb.Send(msg); err != nil {
 			// todo: move msg from draft to sent
 		}
+		if err1 := src.Close(); err == nil {
+			err = err1
+		}
 	case "mv":
 		// todo: defaultfolder
 		if len(os.Args) < 4 {

          
@@ 304,7 310,7 @@ func main() {
 		if msgId, err = mb.Store(mbox, os.Stdin, folder); len(msgId) != 0 {
 			os.Stdout.WriteString(path.Join(folder, msgId) + "\n")
 		}
-	case "pack":
+	case "pack": // rename to sort, as we gonna sort by date
 		if len(os.Args) < 3 {
 			err = missingParams
 			break

          
M command.go +1 -1
@@ 139,7 139,7 @@ func newPlainTextPrinter(dst io.Writer, 
 			_, err = io.Copy(dst, transform.NewReader(in, t))
 			return err
 		}
-		if _, err = fmt.Fprintf(dst, "[MIME Part %d: %s]\n", strconv.Itoa(no), p.Header.Get("Content-Type")); err != nil {
+		if _, err = fmt.Fprintf(dst, "[MIME Part %d: %s]\n", 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

          
M edit.go +23 -13
@@ 156,8 156,10 @@ func encodeMessage(dst io.Writer, msg *m
 
 	h := textproto.MIMEHeader(msg.Header)
 	h.Set("Date", time.Now().Format("Mon, 2 Jan 2006 15:04:05 -0700"))
+	// todo: not utf-8, we use quoted printable!
 	h.Set("Content-Type", "text/plain; charset=utf-8")
 	h.Set("Content-Transfer-Encoding", "quoted-printable")
+	h.Set("Mime-Version", "1.0")
 	if err := writeHeader(buf, h); err != nil {
 		return fmt.Errorf("writing msg header: %s", err)
 	}

          
@@ 249,13 251,14 @@ func fmtReply(dst io.Writer, sender stri
 	// todo: multipart
 	if len(b) == 0 {
 		// non mime msg
+		h := msg.Header
 		if _, err := fmt.Fprintf(dst, "From: %s\nTo: %s\nSubject: Re: %s\nCc: %s\nBcc: \n\n"+
 			"\nOn %s, %s wrote\n\n\n",
-			sender, parseAddressList(msg.Header.Get("From")),
-			dec.safeDecodeHeader(msg.Header.Get("Subject")),
-			parseAddressList(msg.Header.Get("Cc")),
-			dec.safeDecodeHeader(msg.Header.Get("Date")),
-			parseAddressList(msg.Header.Get("From"))); err != nil {
+			sender, parseAddressList(h.Get("From")),
+			dec.safeDecodeHeader(h.Get("Subject")),
+			parseAddressList(h.Get("Cc")),
+			dec.safeDecodeHeader(h.Get("Date")),
+			parseAddressList(h.Get("From"))); err != nil {
 			return err
 		}
 		if err := parse(msg, newPlainTextPrinter(dst, &quoteMessage{true})); err != nil {

          
@@ 287,8 290,9 @@ func parseAddressList(list string) strin
 	return s
 }
 
-func readIntoMimeMessage(src io.Reader) (*mail.Message, error) {
-	tp := textproto.NewReader(bufio.NewReader(src))
+func readIntoMultipartMessage(src io.Reader) (*mail.Message, error) {
+	buf := bufio.NewReader(src)
+	tp := textproto.NewReader(buf)
 
 	hdr, err := tp.ReadMIMEHeader()
 	if err != nil {

          
@@ 299,13 303,14 @@ func readIntoMimeMessage(src io.Reader) 
 		return nil, errors.New("reading mime boundary: " + err.Error())
 	}
 	if len(b) > 0 {
-		// we have a mime message
+		// we have a multipart mime message
 		return mail.ReadMessage(src)
 	}
 	h := md5.New()
 	// h.Write never returns an error
 	io.WriteString(h, strconv.Itoa(time.Now().Nanosecond()))
 	b = fmt.Sprintf("%x", h.Sum(nil))
+
 	var mhdr bytes.Buffer
 	fmt.Fprintf(&mhdr, "\r\n--%s\r\nMIME-Version: 1.0\r\n"+
 		"Content-Type: %s\r\n"+

          
@@ 313,10 318,10 @@ func readIntoMimeMessage(src io.Reader) 
 		"Content-Disposition: inline\r\n\r\n",
 		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("Content-Transfer-Encoding", "7bit")
 	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, buf)}, nil
 }
 
 func boundary(hdr textproto.MIMEHeader) (string, error) {

          
@@ 336,13 341,13 @@ func Attach(mbox Mailbox, dst io.Writer,
 	if err != nil {
 		return err
 	}
-	msg, err := readIntoMimeMessage(src)
+	defer att.Close()
+	msg, err := readIntoMultipartMessage(src)
 	if err != nil {
 		return err
 	}
 	buf := bufio.NewWriter(dst)
 	defer buf.Flush()
-
 	if err = writeHeader(buf, msg.Header); err != nil {
 		return fmt.Errorf("writing msg header: %s", err)
 	}

          
@@ 362,6 367,7 @@ func Attach(mbox Mailbox, dst io.Writer,
 		encoder = base64.NewEncoder(base64.StdEncoding, newLineWriter(buf, 76))
 		encoding = "base64"
 	}
+	defer encoder.Close()
 	hEnc := mime.QEncoding
 	filename = hEnc.Encode("utf-8", path.Base(filename))
 	b, err := boundary(textproto.MIMEHeader(msg.Header))

          
@@ 383,7 389,10 @@ func Attach(mbox Mailbox, dst io.Writer,
 	if _, err = fmt.Fprintf(buf, "\r\n\r\n--%s\r\n", b); err != nil {
 		return err
 	}
-	return buf.Flush()
+	if err = buf.Flush(); err != nil {
+		return err
+	}
+	return att.Close()
 }
 
 type lineWriter struct {

          
@@ 420,6 429,7 @@ func (w *lineWriter) Write(b []byte) (in
 	return n, err
 }
 
+// use \n, as \r\n causes troubles when sending emails
 func writeHeader(dst io.Writer, h map[string][]string) error {
 	enc := mime.QEncoding
 	var b bytes.Buffer