diff options
Diffstat (limited to 'protocol.go')
-rw-r--r-- | protocol.go | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/protocol.go b/protocol.go new file mode 100644 index 0000000..b2a4cb6 --- /dev/null +++ b/protocol.go @@ -0,0 +1,101 @@ +package main + +// postmap -v 'user' /path/to.socket + +import ( + "encoding" + "errors" + "fmt" + "io" + "strings" +) + +// Postfix request. +type Request struct { + Name string + Key string +} + +func (s *Request) UnmarshalText(buf []byte) error { + strs := strings.SplitN(string(buf), " ", 2) + if len(strs) > 0 { + s.Name = strs[0] + } + if len(strs) > 1 { + s.Key = strs[1] + } + if len(strs) > 2 { + return fmt.Errorf("bad format") + } + + return nil +} + +func (s *Request) String() string { + return fmt.Sprintf("%s %s", s.Name, s.Key) +} + +// Value found. +type ReplyOK struct { + Data string +} + +func (s *ReplyOK) String() string { + return fmt.Sprintf("OK %s", s.Data) +} + +// Value not found. +type ReplyNotFound struct{} + +func (s *ReplyNotFound) String() string { + return "NOTFOUND " +} + +// Something happened.. +type ReplyPerm struct { + Reason string +} + +func (s *ReplyPerm) String() string { + return fmt.Sprintf("PERM %s", s.Reason) +} + +func readNetString(r io.Reader, v encoding.TextUnmarshaler) (int, error) { + var strLen int + + bytesRead, err := fmt.Fscanf(r, "%d:", &strLen) + if err != nil { + return bytesRead, err + } + + payload := make([]byte, strLen) + n, err := r.Read(payload) + if err != nil { + return bytesRead, err + } + bytesRead += n + + buf := make([]byte, 1) + n, err = r.Read(buf) + bytesRead += n + if err != nil { + return bytesRead, err + } + + if buf[0] != ',' { + return bytesRead, errors.New("bad format") + } + + err = v.UnmarshalText(payload) + if err != nil { + return bytesRead, err + } + + return bytesRead, nil +} + +func writeNetString(w io.Writer, v fmt.Stringer) (int, error) { + str := v.String() + resp := fmt.Sprintf("%d:%s,", len(str), str) + return w.Write([]byte(resp)) +} |