sieve.go (1913B)
1 // Package sieve provides a client of the ManageSieve protocol 2 // specified in RFC 5804. 3 package sieve 4 5 import ( 6 "crypto/tls" 7 "errors" 8 "fmt" 9 "net/textproto" 10 "os" 11 "strings" 12 ) 13 14 const DefaultPort int = 4190 15 16 func Dial(net, addr string) (*textproto.Conn, error) { 17 conn, err := textproto.Dial(net, addr) 18 if err != nil { 19 return nil, err 20 } 21 for i := 0; i <= 10; i++ { 22 line, err := conn.ReadLine() 23 if err != nil { 24 return nil, err 25 } 26 fmt.Fprintln(os.Stderr, line) 27 if strings.HasPrefix(line, "OK") { 28 break 29 } 30 } 31 return conn, nil 32 } 33 34 // Logout sends the LOGOUT command and closes conn. 35 // Implementations should not use conn afterwards. 36 func Logout(conn *textproto.Conn) error { 37 id, err := conn.Cmd("LOGOUT") 38 if err != nil { 39 return err 40 } 41 conn.StartResponse(id) 42 defer conn.EndResponse(id) 43 line, err := conn.ReadLine() 44 if err != nil { 45 return err 46 } 47 code, msg, found := strings.Cut(line, " ") 48 if code != "OK" { 49 if !found { 50 return fmt.Errorf("logout failed with no message") 51 } 52 return errors.New(msg) 53 } 54 return conn.Close() 55 } 56 57 func Noop(conn *textproto.Conn) error { 58 id, err := conn.Cmd("NOOP") 59 if err != nil { 60 return err 61 } 62 conn.StartResponse(id) 63 defer conn.EndResponse(id) 64 line, err := conn.ReadLine() 65 if err != nil { 66 return err 67 } 68 code, msg, found := strings.Cut(line, " ") 69 if code != "OK" { 70 if !found { 71 return fmt.Errorf("noop failed with no message") 72 } 73 return errors.New(msg) 74 } 75 return nil 76 } 77 78 func StartTLS(conn *textproto.Conn, config *tls.Config) error { 79 id, err := conn.Cmd("STARTTLS") 80 if err != nil { 81 return err 82 } 83 conn.StartResponse(id) 84 defer conn.EndResponse(id) 85 line, err := conn.ReadLine() 86 if err != nil { 87 return err 88 } 89 code, msg, found := strings.Cut(line, " ") 90 if code != "OK" { 91 if !found { 92 return fmt.Errorf("starttls failed with no message") 93 } 94 return errors.New(msg) 95 } 96 return errors.New("TODO not yet implemented") 97 }