...
Source file
src/tawesoft.co.uk/go/legacy/email/util.go
Documentation:
src/tawesoft.co.uk/go/legacy/email/util.go
1 package email
2
3 import (
4 "crypto/rand"
5 "fmt"
6 "io"
7 "mime"
8 "net/mail"
9 "strings"
10 "time"
11 )
12
13
14 func msgid(from mail.Address) string {
15 var rnd = make([]byte, 16)
16 rand.Read(rnd)
17 var tnow = time.Now().UTC().Format("20060102150405")
18 var domain = "localhost"
19
20 var atpos = strings.LastIndexByte(from.Address, '@')
21 if atpos > 0 {
22 domain = from.Address[atpos:]
23 }
24
25 return fmt.Sprintf("<%s.%x%s>", tnow, rnd, domain)
26 }
27
28
29 func strall(
30 xs string,
31 f func(c rune) bool,
32 ) bool {
33 for _, x := range xs {
34
35 if !f(x) { return false }
36 }
37
38 return true
39 }
40
41
42 func optionalQEncode(x string) string {
43 var onlyPrintableAscii = func(c rune) bool {
44 return (c >= 0x20) && (c <= 0x7e)
45 }
46
47 if strall(x, onlyPrintableAscii) {
48 return x
49 } else {
50 return mime.QEncoding.Encode("utf-8", x)
51 }
52 }
53
54
55 type lineBreaker struct {
56 column int
57 writer io.Writer
58 }
59
60
61
62 func (lb lineBreaker) Write(p []byte) (n int, err error) {
63
64 const LIMIT = 76
65 var offset int
66 var written int
67 lb.column += len(p)
68
69 for offset = 0; lb.column >= 76; lb.column -= LIMIT {
70 n, err := lb.writer.Write(p[offset:offset + LIMIT])
71 written += n
72 if err != nil { return written, err }
73
74 offset += LIMIT
75
76 if offset != len(p) {
77 n, err := io.WriteString(lb.writer, "\r\n")
78 written += n
79 if err != nil { return written, err }
80 }
81 }
82
83 if offset != len(p) {
84 n, err := lb.writer.Write(p[offset:])
85 written += n
86 if err != nil { return written, err }
87 }
88
89 return written, nil
90 }
91
View as plain text