protocol.go (1656B)
1 package main 2 3 // postmap -v 'user' /path/to.socket 4 5 import ( 6 "encoding" 7 "errors" 8 "fmt" 9 "io" 10 "strings" 11 ) 12 13 // Postfix request. 14 type Request struct { 15 Name string 16 Key string 17 } 18 19 func (s *Request) UnmarshalText(buf []byte) error { 20 strs := strings.SplitN(string(buf), " ", 2) 21 if len(strs) > 0 { 22 s.Name = strs[0] 23 } 24 if len(strs) > 1 { 25 s.Key = strs[1] 26 } 27 if len(strs) > 2 { 28 return fmt.Errorf("bad format") 29 } 30 31 return nil 32 } 33 34 func (s *Request) String() string { 35 return fmt.Sprintf("%s %s", s.Name, s.Key) 36 } 37 38 // Value found. 39 type ReplyOK struct { 40 Data string 41 } 42 43 func (s *ReplyOK) String() string { 44 return fmt.Sprintf("OK %s", s.Data) 45 } 46 47 // Value not found. 48 type ReplyNotFound struct{} 49 50 func (s *ReplyNotFound) String() string { 51 return "NOTFOUND " 52 } 53 54 // Something happened.. 55 type ReplyPerm struct { 56 Reason string 57 } 58 59 func (s *ReplyPerm) String() string { 60 return fmt.Sprintf("PERM %s", s.Reason) 61 } 62 63 func readNetString(r io.Reader, v encoding.TextUnmarshaler) (int, error) { 64 var strLen int 65 66 bytesRead, err := fmt.Fscanf(r, "%d:", &strLen) 67 if err != nil { 68 return bytesRead, err 69 } 70 71 payload := make([]byte, strLen) 72 n, err := r.Read(payload) 73 if err != nil { 74 return bytesRead, err 75 } 76 bytesRead += n 77 78 buf := make([]byte, 1) 79 n, err = r.Read(buf) 80 bytesRead += n 81 if err != nil { 82 return bytesRead, err 83 } 84 85 if buf[0] != ',' { 86 return bytesRead, errors.New("bad format") 87 } 88 89 err = v.UnmarshalText(payload) 90 if err != nil { 91 return bytesRead, err 92 } 93 94 return bytesRead, nil 95 } 96 97 func writeNetString(w io.Writer, v fmt.Stringer) (int, error) { 98 str := v.String() 99 resp := fmt.Sprintf("%d:%s,", len(str), str) 100 return w.Write([]byte(resp)) 101 }