package smtpserver import ( "fmt" "os" "github.com/mjl-/mox/dsn" "github.com/mjl-/mox/queue" "github.com/mjl-/mox/smtp" "github.com/mjl-/mox/store" ) // compose dsn message and add it to the queue for delivery to rcptTo. func queueDSN(c *conn, rcptTo smtp.Path, m dsn.Message) error { buf, err := m.Compose(c.log, false) if err != nil { return err } var bufUTF8 []byte if c.smtputf8 { bufUTF8, err = m.Compose(c.log, true) if err != nil { c.log.Errorx("composing dsn with utf-8 for incoming delivery for unknown user, continuing with ascii-only dsn", err) } } f, err := store.CreateMessageTemp("smtp-dsn") if err != nil { return fmt.Errorf("creating temp file: %w", err) } defer func() { if f != nil { if err := os.Remove(f.Name()); err != nil { c.log.Errorx("removing temporary dsn message file", err) } f.Close() } }() if _, err := f.Write([]byte(buf)); err != nil { return fmt.Errorf("writing dsn file: %w", err) } // Queue DSN with null reverse path so failures to deliver will eventually drop the // message instead of causing delivery loops. // ../rfc/3464:433 const has8bit = false const smtputf8 = false if err := queue.Add(c.log, "", smtp.Path{}, rcptTo, has8bit, smtputf8, int64(len(buf)), nil, f, bufUTF8, true); err != nil { return err } if err := f.Close(); err != nil { c.log.Errorx("closing dsn file", err) } f = nil return nil }