x

Programs, configuration and documentation that don't fit anywhere else
Log | Files | Refs | README | LICENSE

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 }